1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_chart2.hxx"
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski #include "StockDataInterpreter.hxx"
28*b1cdbd2cSJim Jagielski #include "DataSeries.hxx"
29*b1cdbd2cSJim Jagielski #include "macros.hxx"
30*b1cdbd2cSJim Jagielski #include "DataSeriesHelper.hxx"
31*b1cdbd2cSJim Jagielski #include "CommonConverters.hxx"
32*b1cdbd2cSJim Jagielski #include "ContainerHelper.hxx"
33*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/XPropertySet.hpp>
34*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/data/XDataSink.hpp>
35*b1cdbd2cSJim Jagielski
36*b1cdbd2cSJim Jagielski // #include <deque>
37*b1cdbd2cSJim Jagielski
38*b1cdbd2cSJim Jagielski #include <vector>
39*b1cdbd2cSJim Jagielski #include <algorithm>
40*b1cdbd2cSJim Jagielski #include <iterator>
41*b1cdbd2cSJim Jagielski
42*b1cdbd2cSJim Jagielski using namespace ::com::sun::star;
43*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::chart2;
44*b1cdbd2cSJim Jagielski using namespace ::std;
45*b1cdbd2cSJim Jagielski
46*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Reference;
47*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Sequence;
48*b1cdbd2cSJim Jagielski using ::rtl::OUString;
49*b1cdbd2cSJim Jagielski using namespace ::chart::ContainerHelper;
50*b1cdbd2cSJim Jagielski
51*b1cdbd2cSJim Jagielski namespace chart
52*b1cdbd2cSJim Jagielski {
53*b1cdbd2cSJim Jagielski
54*b1cdbd2cSJim Jagielski // explicit
StockDataInterpreter(StockChartTypeTemplate::StockVariant eVariant,const Reference<uno::XComponentContext> & xContext)55*b1cdbd2cSJim Jagielski StockDataInterpreter::StockDataInterpreter(
56*b1cdbd2cSJim Jagielski StockChartTypeTemplate::StockVariant eVariant,
57*b1cdbd2cSJim Jagielski const Reference< uno::XComponentContext > & xContext ) :
58*b1cdbd2cSJim Jagielski DataInterpreter( xContext ),
59*b1cdbd2cSJim Jagielski m_eStockVariant( eVariant )
60*b1cdbd2cSJim Jagielski {}
61*b1cdbd2cSJim Jagielski
~StockDataInterpreter()62*b1cdbd2cSJim Jagielski StockDataInterpreter::~StockDataInterpreter()
63*b1cdbd2cSJim Jagielski {}
64*b1cdbd2cSJim Jagielski
GetStockVariant() const65*b1cdbd2cSJim Jagielski StockChartTypeTemplate::StockVariant StockDataInterpreter::GetStockVariant() const
66*b1cdbd2cSJim Jagielski {
67*b1cdbd2cSJim Jagielski return m_eStockVariant;
68*b1cdbd2cSJim Jagielski }
69*b1cdbd2cSJim Jagielski
70*b1cdbd2cSJim Jagielski // ____ XDataInterpreter ____
interpretDataSource(const Reference<data::XDataSource> & xSource,const Sequence<beans::PropertyValue> & rArguments,const Sequence<Reference<XDataSeries>> & rSeriesToReUse)71*b1cdbd2cSJim Jagielski InterpretedData SAL_CALL StockDataInterpreter::interpretDataSource(
72*b1cdbd2cSJim Jagielski const Reference< data::XDataSource >& xSource,
73*b1cdbd2cSJim Jagielski const Sequence< beans::PropertyValue >& rArguments,
74*b1cdbd2cSJim Jagielski const Sequence< Reference< XDataSeries > >& rSeriesToReUse )
75*b1cdbd2cSJim Jagielski throw (uno::RuntimeException)
76*b1cdbd2cSJim Jagielski {
77*b1cdbd2cSJim Jagielski if( ! xSource.is())
78*b1cdbd2cSJim Jagielski return InterpretedData();
79*b1cdbd2cSJim Jagielski
80*b1cdbd2cSJim Jagielski Reference< data::XLabeledDataSequence > xCategories;
81*b1cdbd2cSJim Jagielski Sequence< Reference< data::XLabeledDataSequence > > aData( xSource->getDataSequences() );
82*b1cdbd2cSJim Jagielski const sal_Int32 nDataCount( aData.getLength());
83*b1cdbd2cSJim Jagielski
84*b1cdbd2cSJim Jagielski // sub-type properties
85*b1cdbd2cSJim Jagielski const StockChartTypeTemplate::StockVariant eVar( GetStockVariant());
86*b1cdbd2cSJim Jagielski const bool bHasOpenValues (( eVar == StockChartTypeTemplate::OPEN_LOW_HI_CLOSE ) ||
87*b1cdbd2cSJim Jagielski ( eVar == StockChartTypeTemplate::VOL_OPEN_LOW_HI_CLOSE ));
88*b1cdbd2cSJim Jagielski const bool bHasVolume (( eVar == StockChartTypeTemplate::VOL_LOW_HI_CLOSE ) ||
89*b1cdbd2cSJim Jagielski ( eVar == StockChartTypeTemplate::VOL_OPEN_LOW_HI_CLOSE ));
90*b1cdbd2cSJim Jagielski const bool bHasCategories( HasCategories( rArguments, aData ));
91*b1cdbd2cSJim Jagielski
92*b1cdbd2cSJim Jagielski // necessary roles for "full series"
93*b1cdbd2cSJim Jagielski // low/high/close
94*b1cdbd2cSJim Jagielski sal_Int32 nNumberOfNecessarySequences( 3 );
95*b1cdbd2cSJim Jagielski if( bHasOpenValues )
96*b1cdbd2cSJim Jagielski ++nNumberOfNecessarySequences;
97*b1cdbd2cSJim Jagielski if( bHasVolume )
98*b1cdbd2cSJim Jagielski ++nNumberOfNecessarySequences;
99*b1cdbd2cSJim Jagielski
100*b1cdbd2cSJim Jagielski // calculate number of full series (nNumOfFullSeries) and the number of remaining
101*b1cdbd2cSJim Jagielski // sequences used for additional "incomplete series" (nRemaining)
102*b1cdbd2cSJim Jagielski sal_Int32 nNumOfFullSeries( 0 );
103*b1cdbd2cSJim Jagielski sal_Int32 nRemaining( 0 );
104*b1cdbd2cSJim Jagielski {
105*b1cdbd2cSJim Jagielski sal_Int32 nAvailableSequences( nDataCount );
106*b1cdbd2cSJim Jagielski if( bHasCategories )
107*b1cdbd2cSJim Jagielski --nAvailableSequences;
108*b1cdbd2cSJim Jagielski nNumOfFullSeries = nAvailableSequences / nNumberOfNecessarySequences;
109*b1cdbd2cSJim Jagielski nRemaining = nAvailableSequences % nNumberOfNecessarySequences;
110*b1cdbd2cSJim Jagielski }
111*b1cdbd2cSJim Jagielski sal_Int32 nCandleStickSeries = nNumOfFullSeries;
112*b1cdbd2cSJim Jagielski sal_Int32 nVolumeSeries = nNumOfFullSeries;
113*b1cdbd2cSJim Jagielski
114*b1cdbd2cSJim Jagielski sal_Int32 nNumberOfGroups( bHasVolume ? 2 : 1 );
115*b1cdbd2cSJim Jagielski // sequences of data::XLabeledDataSequence per series per group
116*b1cdbd2cSJim Jagielski Sequence< Sequence< Sequence< Reference< data::XLabeledDataSequence > > > > aSequences( nNumberOfGroups );
117*b1cdbd2cSJim Jagielski sal_Int32 nBarGroupIndex( 0 );
118*b1cdbd2cSJim Jagielski sal_Int32 nCandleStickGroupIndex( nNumberOfGroups - 1 );
119*b1cdbd2cSJim Jagielski
120*b1cdbd2cSJim Jagielski // allocate space for labeled sequences
121*b1cdbd2cSJim Jagielski if( nRemaining > 0 )
122*b1cdbd2cSJim Jagielski ++nCandleStickSeries;
123*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex].realloc( nCandleStickSeries );
124*b1cdbd2cSJim Jagielski if( bHasVolume )
125*b1cdbd2cSJim Jagielski {
126*b1cdbd2cSJim Jagielski // if there are remaining sequences, the first one is taken for
127*b1cdbd2cSJim Jagielski // additional close values, the second one is taken as volume, if volume
128*b1cdbd2cSJim Jagielski // is used
129*b1cdbd2cSJim Jagielski if( nRemaining > 1 )
130*b1cdbd2cSJim Jagielski ++nVolumeSeries;
131*b1cdbd2cSJim Jagielski aSequences[nBarGroupIndex].realloc( nVolumeSeries );
132*b1cdbd2cSJim Jagielski }
133*b1cdbd2cSJim Jagielski
134*b1cdbd2cSJim Jagielski
135*b1cdbd2cSJim Jagielski // create data
136*b1cdbd2cSJim Jagielski sal_Int32 nSourceIndex = 0; // index into aData sequence
137*b1cdbd2cSJim Jagielski
138*b1cdbd2cSJim Jagielski // 1. categories
139*b1cdbd2cSJim Jagielski if( bHasCategories )
140*b1cdbd2cSJim Jagielski {
141*b1cdbd2cSJim Jagielski xCategories.set( aData[nSourceIndex] );
142*b1cdbd2cSJim Jagielski ++nSourceIndex;
143*b1cdbd2cSJim Jagielski }
144*b1cdbd2cSJim Jagielski
145*b1cdbd2cSJim Jagielski // 2. create "full" series
146*b1cdbd2cSJim Jagielski for( sal_Int32 nLabeledSeqIdx=0; nLabeledSeqIdx<nNumOfFullSeries; ++nLabeledSeqIdx )
147*b1cdbd2cSJim Jagielski {
148*b1cdbd2cSJim Jagielski // bar
149*b1cdbd2cSJim Jagielski if( bHasVolume )
150*b1cdbd2cSJim Jagielski {
151*b1cdbd2cSJim Jagielski aSequences[nBarGroupIndex][nLabeledSeqIdx].realloc( 1 );
152*b1cdbd2cSJim Jagielski aSequences[nBarGroupIndex][nLabeledSeqIdx][0].set( aData[nSourceIndex] );
153*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
154*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-y"));
155*b1cdbd2cSJim Jagielski ++nSourceIndex;
156*b1cdbd2cSJim Jagielski }
157*b1cdbd2cSJim Jagielski
158*b1cdbd2cSJim Jagielski sal_Int32 nSeqIdx = 0;
159*b1cdbd2cSJim Jagielski if( bHasOpenValues )
160*b1cdbd2cSJim Jagielski {
161*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nLabeledSeqIdx].realloc( 4 );
162*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nLabeledSeqIdx][nSeqIdx].set( aData[nSourceIndex] );
163*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
164*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-first"));
165*b1cdbd2cSJim Jagielski ++nSourceIndex, ++nSeqIdx;
166*b1cdbd2cSJim Jagielski }
167*b1cdbd2cSJim Jagielski else
168*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nLabeledSeqIdx].realloc( 3 );
169*b1cdbd2cSJim Jagielski
170*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nLabeledSeqIdx][nSeqIdx].set( aData[nSourceIndex] );
171*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
172*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-min"));
173*b1cdbd2cSJim Jagielski ++nSourceIndex, ++nSeqIdx;
174*b1cdbd2cSJim Jagielski
175*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nLabeledSeqIdx][nSeqIdx].set( aData[nSourceIndex] );
176*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
177*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-max"));
178*b1cdbd2cSJim Jagielski ++nSourceIndex, ++nSeqIdx;
179*b1cdbd2cSJim Jagielski
180*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nLabeledSeqIdx][nSeqIdx].set( aData[nSourceIndex] );
181*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
182*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-last"));
183*b1cdbd2cSJim Jagielski ++nSourceIndex, ++nSeqIdx;
184*b1cdbd2cSJim Jagielski }
185*b1cdbd2cSJim Jagielski
186*b1cdbd2cSJim Jagielski // 3. create series with remaining sequences
187*b1cdbd2cSJim Jagielski if( bHasVolume && nRemaining > 1 )
188*b1cdbd2cSJim Jagielski {
189*b1cdbd2cSJim Jagielski OSL_ASSERT( nVolumeSeries > nNumOfFullSeries );
190*b1cdbd2cSJim Jagielski aSequences[nBarGroupIndex][nVolumeSeries - 1].realloc( 1 );
191*b1cdbd2cSJim Jagielski OSL_ASSERT( nDataCount > nSourceIndex );
192*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
193*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-y"));
194*b1cdbd2cSJim Jagielski aSequences[nBarGroupIndex][nVolumeSeries - 1][0].set( aData[nSourceIndex] );
195*b1cdbd2cSJim Jagielski ++nSourceIndex;
196*b1cdbd2cSJim Jagielski --nRemaining;
197*b1cdbd2cSJim Jagielski OSL_ENSURE( nRemaining, "additional bar should only be used if there is at least one more sequence for a candle stick" );
198*b1cdbd2cSJim Jagielski }
199*b1cdbd2cSJim Jagielski
200*b1cdbd2cSJim Jagielski // candle-stick
201*b1cdbd2cSJim Jagielski if( nRemaining > 0 )
202*b1cdbd2cSJim Jagielski {
203*b1cdbd2cSJim Jagielski OSL_ASSERT( nCandleStickSeries > nNumOfFullSeries );
204*b1cdbd2cSJim Jagielski const sal_Int32 nSeriesIndex = nCandleStickSeries - 1;
205*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nSeriesIndex].realloc( nRemaining );
206*b1cdbd2cSJim Jagielski OSL_ASSERT( nDataCount > nSourceIndex );
207*b1cdbd2cSJim Jagielski
208*b1cdbd2cSJim Jagielski // 1. low
209*b1cdbd2cSJim Jagielski sal_Int32 nSeqIdx( 0 );
210*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nSeriesIndex][nSeqIdx].set( aData[nSourceIndex] );
211*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
212*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-min"));
213*b1cdbd2cSJim Jagielski ++nSourceIndex, ++nSeqIdx;
214*b1cdbd2cSJim Jagielski
215*b1cdbd2cSJim Jagielski // 2. high
216*b1cdbd2cSJim Jagielski if( nSeqIdx < nRemaining )
217*b1cdbd2cSJim Jagielski {
218*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nSeriesIndex][nSeqIdx].set( aData[nSourceIndex] );
219*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
220*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-max"));
221*b1cdbd2cSJim Jagielski ++nSourceIndex, ++nSeqIdx;
222*b1cdbd2cSJim Jagielski }
223*b1cdbd2cSJim Jagielski
224*b1cdbd2cSJim Jagielski // 3. close
225*b1cdbd2cSJim Jagielski OSL_ENSURE( bHasOpenValues || nSeqIdx >= nRemaining, "could have created full series" );
226*b1cdbd2cSJim Jagielski if( nSeqIdx < nRemaining )
227*b1cdbd2cSJim Jagielski {
228*b1cdbd2cSJim Jagielski aSequences[nCandleStickGroupIndex][nSeriesIndex][nSeqIdx].set( aData[nSourceIndex] );
229*b1cdbd2cSJim Jagielski if( aData[nSourceIndex].is())
230*b1cdbd2cSJim Jagielski SetRole( aData[nSourceIndex]->getValues(), C2U("values-last"));
231*b1cdbd2cSJim Jagielski ++nSourceIndex, ++nSeqIdx;
232*b1cdbd2cSJim Jagielski }
233*b1cdbd2cSJim Jagielski
234*b1cdbd2cSJim Jagielski // 4. open
235*b1cdbd2cSJim Jagielski OSL_ENSURE( nSeqIdx >= nRemaining, "could have created full series" );
236*b1cdbd2cSJim Jagielski }
237*b1cdbd2cSJim Jagielski
238*b1cdbd2cSJim Jagielski // create DataSeries
239*b1cdbd2cSJim Jagielski Sequence< Sequence< Reference< XDataSeries > > > aResultSeries( nNumberOfGroups );
240*b1cdbd2cSJim Jagielski sal_Int32 nGroupIndex, nReUsedSeriesIdx = 0;
241*b1cdbd2cSJim Jagielski for( nGroupIndex=0; nGroupIndex<nNumberOfGroups; ++nGroupIndex )
242*b1cdbd2cSJim Jagielski {
243*b1cdbd2cSJim Jagielski const sal_Int32 nNumSeriesData = aSequences[nGroupIndex].getLength();
244*b1cdbd2cSJim Jagielski aResultSeries[nGroupIndex].realloc( nNumSeriesData );
245*b1cdbd2cSJim Jagielski for( sal_Int32 nSeriesIdx = 0; nSeriesIdx < nNumSeriesData; ++nSeriesIdx, ++nReUsedSeriesIdx )
246*b1cdbd2cSJim Jagielski {
247*b1cdbd2cSJim Jagielski try
248*b1cdbd2cSJim Jagielski {
249*b1cdbd2cSJim Jagielski Reference< XDataSeries > xSeries;
250*b1cdbd2cSJim Jagielski if( nReUsedSeriesIdx < rSeriesToReUse.getLength())
251*b1cdbd2cSJim Jagielski xSeries.set( rSeriesToReUse[nReUsedSeriesIdx] );
252*b1cdbd2cSJim Jagielski else
253*b1cdbd2cSJim Jagielski xSeries.set( new DataSeries( GetComponentContext() ) );
254*b1cdbd2cSJim Jagielski OSL_ASSERT( xSeries.is() );
255*b1cdbd2cSJim Jagielski Reference< data::XDataSink > xSink( xSeries, uno::UNO_QUERY_THROW );
256*b1cdbd2cSJim Jagielski OSL_ASSERT( xSink.is() );
257*b1cdbd2cSJim Jagielski xSink->setData( aSequences[nGroupIndex][nSeriesIdx] );
258*b1cdbd2cSJim Jagielski aResultSeries[nGroupIndex][nSeriesIdx].set( xSeries );
259*b1cdbd2cSJim Jagielski }
260*b1cdbd2cSJim Jagielski catch( uno::Exception & ex )
261*b1cdbd2cSJim Jagielski {
262*b1cdbd2cSJim Jagielski ASSERT_EXCEPTION( ex );
263*b1cdbd2cSJim Jagielski }
264*b1cdbd2cSJim Jagielski }
265*b1cdbd2cSJim Jagielski }
266*b1cdbd2cSJim Jagielski
267*b1cdbd2cSJim Jagielski return InterpretedData( aResultSeries, xCategories );
268*b1cdbd2cSJim Jagielski }
269*b1cdbd2cSJim Jagielski
270*b1cdbd2cSJim Jagielski // criterion: there must be two groups for stock-charts with volume and all
271*b1cdbd2cSJim Jagielski // series must have the correct number of data::XLabeledDataSequences
272*b1cdbd2cSJim Jagielski
273*b1cdbd2cSJim Jagielski // todo: skip first criterion? (to allow easy switch from stock-chart without
274*b1cdbd2cSJim Jagielski // volume to one with volume)
isDataCompatible(const InterpretedData & aInterpretedData)275*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL StockDataInterpreter::isDataCompatible(
276*b1cdbd2cSJim Jagielski const InterpretedData& aInterpretedData )
277*b1cdbd2cSJim Jagielski throw (uno::RuntimeException)
278*b1cdbd2cSJim Jagielski {
279*b1cdbd2cSJim Jagielski // high/low/close
280*b1cdbd2cSJim Jagielski sal_Int32 nNumberOfNecessarySequences = 3;
281*b1cdbd2cSJim Jagielski // open
282*b1cdbd2cSJim Jagielski StockChartTypeTemplate::StockVariant eVar( GetStockVariant());
283*b1cdbd2cSJim Jagielski if( ( eVar == StockChartTypeTemplate::OPEN_LOW_HI_CLOSE ) ||
284*b1cdbd2cSJim Jagielski ( eVar == StockChartTypeTemplate::VOL_OPEN_LOW_HI_CLOSE ))
285*b1cdbd2cSJim Jagielski ++nNumberOfNecessarySequences;
286*b1cdbd2cSJim Jagielski // volume
287*b1cdbd2cSJim Jagielski bool bHasVolume = (( eVar == StockChartTypeTemplate::VOL_LOW_HI_CLOSE ) ||
288*b1cdbd2cSJim Jagielski ( eVar == StockChartTypeTemplate::VOL_OPEN_LOW_HI_CLOSE ));
289*b1cdbd2cSJim Jagielski
290*b1cdbd2cSJim Jagielski // 1. correct number of sub-types
291*b1cdbd2cSJim Jagielski if( aInterpretedData.Series.getLength() < (bHasVolume ? 2 : 1 ))
292*b1cdbd2cSJim Jagielski return sal_False;
293*b1cdbd2cSJim Jagielski
294*b1cdbd2cSJim Jagielski // 2. a. volume -- use default check
295*b1cdbd2cSJim Jagielski if( bHasVolume )
296*b1cdbd2cSJim Jagielski {
297*b1cdbd2cSJim Jagielski if( ! DataInterpreter::isDataCompatible(
298*b1cdbd2cSJim Jagielski InterpretedData( Sequence< Sequence< Reference< XDataSeries > > >(
299*b1cdbd2cSJim Jagielski aInterpretedData.Series.getConstArray(), 1 ),
300*b1cdbd2cSJim Jagielski aInterpretedData.Categories )))
301*b1cdbd2cSJim Jagielski return sal_False;
302*b1cdbd2cSJim Jagielski }
303*b1cdbd2cSJim Jagielski
304*b1cdbd2cSJim Jagielski // 2. b. candlestick
305*b1cdbd2cSJim Jagielski {
306*b1cdbd2cSJim Jagielski OSL_ASSERT( aInterpretedData.Series.getLength() > (bHasVolume ? 1 : 0));
307*b1cdbd2cSJim Jagielski Sequence< Reference< XDataSeries > > aSeries( aInterpretedData.Series[(bHasVolume ? 1 : 0)] );
308*b1cdbd2cSJim Jagielski if(!aSeries.getLength())
309*b1cdbd2cSJim Jagielski return sal_False;
310*b1cdbd2cSJim Jagielski for( sal_Int32 i=0; i<aSeries.getLength(); ++i )
311*b1cdbd2cSJim Jagielski {
312*b1cdbd2cSJim Jagielski try
313*b1cdbd2cSJim Jagielski {
314*b1cdbd2cSJim Jagielski Reference< data::XDataSource > xSrc( aSeries[i], uno::UNO_QUERY_THROW );
315*b1cdbd2cSJim Jagielski Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSrc->getDataSequences());
316*b1cdbd2cSJim Jagielski if( aSeq.getLength() != nNumberOfNecessarySequences )
317*b1cdbd2cSJim Jagielski return sal_False;
318*b1cdbd2cSJim Jagielski }
319*b1cdbd2cSJim Jagielski catch( uno::Exception & ex )
320*b1cdbd2cSJim Jagielski {
321*b1cdbd2cSJim Jagielski ASSERT_EXCEPTION( ex );
322*b1cdbd2cSJim Jagielski }
323*b1cdbd2cSJim Jagielski }
324*b1cdbd2cSJim Jagielski }
325*b1cdbd2cSJim Jagielski
326*b1cdbd2cSJim Jagielski // 2. c. additional series
327*b1cdbd2cSJim Jagielski // ignore
328*b1cdbd2cSJim Jagielski
329*b1cdbd2cSJim Jagielski return sal_True;
330*b1cdbd2cSJim Jagielski }
331*b1cdbd2cSJim Jagielski
reinterpretDataSeries(const InterpretedData & aInterpretedData)332*b1cdbd2cSJim Jagielski InterpretedData SAL_CALL StockDataInterpreter::reinterpretDataSeries(
333*b1cdbd2cSJim Jagielski const InterpretedData& aInterpretedData )
334*b1cdbd2cSJim Jagielski throw (uno::RuntimeException)
335*b1cdbd2cSJim Jagielski {
336*b1cdbd2cSJim Jagielski // prerequisite: StockDataInterpreter::isDataCompatible() returned true
337*b1cdbd2cSJim Jagielski return aInterpretedData;
338*b1cdbd2cSJim Jagielski }
339*b1cdbd2cSJim Jagielski
340*b1cdbd2cSJim Jagielski } // namespace chart
341