update dev300-m58
[ooovba.git] / chart2 / source / tools / RegressionCurveHelper.cxx
blobe821c8d4e1d58ca02ef14033b6b9d326477a3296
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: RegressionCurveHelper.cxx,v $
10 * $Revision: 1.15.16.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "RegressionCurveHelper.hxx"
34 #include "MeanValueRegressionCurveCalculator.hxx"
35 #include "LinearRegressionCurveCalculator.hxx"
36 #include "LogarithmicRegressionCurveCalculator.hxx"
37 #include "ExponentialRegressionCurveCalculator.hxx"
38 #include "PotentialRegressionCurveCalculator.hxx"
39 #include "CommonConverters.hxx"
40 #include "RegressionCurveModel.hxx"
41 #include "ChartTypeHelper.hxx"
42 #include "ChartModelHelper.hxx"
43 #include "macros.hxx"
44 #include "PropertyHelper.hxx"
45 #include "ResId.hxx"
46 #include "Strings.hrc"
47 #include "DiagramHelper.hxx"
48 #include <com/sun/star/chart2/XChartDocument.hpp>
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::chart2;
53 using ::com::sun::star::uno::Reference;
54 using ::com::sun::star::uno::Sequence;
55 using ::com::sun::star::uno::XComponentContext;
56 using ::com::sun::star::lang::XServiceName;
57 using ::com::sun::star::beans::XPropertySet;
58 using ::com::sun::star::uno::Exception;
59 using ::rtl::OUString;
61 namespace
63 OUString lcl_getServiceNameForType( ::chart::RegressionCurveHelper::tRegressionType eType )
65 OUString aServiceName;
66 switch( eType )
68 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_LINEAR:
69 aServiceName = C2U( "com.sun.star.chart2.LinearRegressionCurve" );
70 break;
71 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_LOG:
72 aServiceName = C2U( "com.sun.star.chart2.LogarithmicRegressionCurve" );
73 break;
74 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_EXP:
75 aServiceName = C2U( "com.sun.star.chart2.ExponentialRegressionCurve" );
76 break;
77 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_POWER:
78 aServiceName = C2U( "com.sun.star.chart2.PotentialRegressionCurve" );
79 break;
80 default:
81 OSL_ENSURE(false,"unknown regression curve type - use linear instead");
82 aServiceName = C2U( "com.sun.star.chart2.LinearRegressionCurve" );
83 break;
85 return aServiceName;
87 } // anonymous namespace
89 //.............................................................................
90 namespace chart
92 //.............................................................................
94 // static
95 Reference< XRegressionCurve > RegressionCurveHelper::createMeanValueLine(
96 const Reference< XComponentContext > & xContext )
98 return Reference< XRegressionCurve >(
99 new MeanValueRegressionCurve( xContext ));
102 // static
103 Reference< XRegressionCurve > RegressionCurveHelper::createRegressionCurveByServiceName(
104 const Reference< XComponentContext > & xContext,
105 ::rtl::OUString aServiceName )
107 Reference< XRegressionCurve > xResult;
109 // todo: use factory methods with service name
110 if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
111 "com.sun.star.chart2.LinearRegressionCurve" )))
113 xResult.set(
114 new LinearRegressionCurve( xContext ));
116 else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
117 "com.sun.star.chart2.LogarithmicRegressionCurve" )))
119 xResult.set(
120 new LogarithmicRegressionCurve( xContext ));
122 else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
123 "com.sun.star.chart2.ExponentialRegressionCurve" )))
125 xResult.set(
126 new ExponentialRegressionCurve( xContext ));
128 else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
129 "com.sun.star.chart2.PotentialRegressionCurve" )))
131 xResult.set(
132 new PotentialRegressionCurve( xContext ));
135 return xResult;
138 // ------------------------------------------------------------
140 // static
141 Reference< XRegressionCurveCalculator > RegressionCurveHelper::createRegressionCurveCalculatorByServiceName(
142 ::rtl::OUString aServiceName )
144 Reference< XRegressionCurveCalculator > xResult;
146 // todo: use factory methods with service name
147 if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
148 "com.sun.star.chart2.MeanValueRegressionCurve" )))
150 xResult.set( new MeanValueRegressionCurveCalculator());
152 if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
153 "com.sun.star.chart2.LinearRegressionCurve" )))
155 xResult.set( new LinearRegressionCurveCalculator());
157 else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
158 "com.sun.star.chart2.LogarithmicRegressionCurve" )))
160 xResult.set( new LogarithmicRegressionCurveCalculator());
162 else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
163 "com.sun.star.chart2.ExponentialRegressionCurve" )))
165 xResult.set( new ExponentialRegressionCurveCalculator());
167 else if( aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
168 "com.sun.star.chart2.PotentialRegressionCurve" )))
170 xResult.set( new PotentialRegressionCurveCalculator());
173 return xResult;
176 // static
177 void RegressionCurveHelper::initializeCurveCalculator(
178 const Reference< XRegressionCurveCalculator > & xOutCurveCalculator,
179 const Reference< data::XDataSource > & xSource,
180 bool bUseXValuesIfAvailable /* = true */ )
182 if( ! (xOutCurveCalculator.is() &&
183 xSource.is() ))
184 return;
186 Sequence< double > aXValues, aYValues;
187 bool bXValuesFound = false, bYValuesFound = false;
189 Sequence< Reference< data::XLabeledDataSequence > > aDataSeqs( xSource->getDataSequences());
190 sal_Int32 i = 0;
191 for( i=0;
192 ! (bXValuesFound && bYValuesFound) && i<aDataSeqs.getLength();
193 ++i )
197 Reference< data::XDataSequence > xSeq( aDataSeqs[i]->getValues());
198 Reference< XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
199 ::rtl::OUString aRole;
200 if( xProp->getPropertyValue(
201 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Role" ))) >>= aRole )
203 if( bUseXValuesIfAvailable &&
204 ! bXValuesFound &&
205 aRole.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "values-x" )))
207 aXValues = DataSequenceToDoubleSequence( xSeq );
208 bXValuesFound = true;
210 else if( ! bYValuesFound &&
211 aRole.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "values-y" )))
213 aYValues = DataSequenceToDoubleSequence( xSeq );
214 bYValuesFound = true;
218 catch( Exception & ex )
220 ASSERT_EXCEPTION( ex );
224 if( ! bXValuesFound &&
225 bYValuesFound )
227 // initialize with 1, 2, ...
228 //first category (index 0) matches with real number 1.0
229 aXValues.realloc( aYValues.getLength());
230 for( i=0; i<aXValues.getLength(); ++i )
231 aXValues[i] = i+1;
232 bXValuesFound = true;
235 if( bXValuesFound && bYValuesFound &&
236 aXValues.getLength() > 0 &&
237 aYValues.getLength() > 0 )
238 xOutCurveCalculator->recalculateRegression( aXValues, aYValues );
241 // static
242 void RegressionCurveHelper::initializeCurveCalculator(
243 const Reference< XRegressionCurveCalculator > & xOutCurveCalculator,
244 const Reference< XDataSeries > & xSeries,
245 const Reference< frame::XModel > & xModel )
247 sal_Int32 nAxisType = ChartTypeHelper::getAxisType(
248 ChartModelHelper::getChartTypeOfSeries( xModel, xSeries ), 0 ); // x-axis
250 initializeCurveCalculator( xOutCurveCalculator,
251 uno::Reference< data::XDataSource >( xSeries, uno::UNO_QUERY ),
252 (nAxisType == AxisType::REALNUMBER) );
255 // ----------------------------------------
257 // static
258 bool RegressionCurveHelper::hasMeanValueLine(
259 const uno::Reference< XRegressionCurveContainer > & xRegCnt )
261 if( !xRegCnt.is())
262 return false;
266 uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
267 xRegCnt->getRegressionCurves());
268 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
270 if( isMeanValueLine( aCurves[i] ))
271 return true;
274 catch( Exception & ex )
276 ASSERT_EXCEPTION( ex );
279 return false;
282 // static
283 bool RegressionCurveHelper::isMeanValueLine(
284 const uno::Reference< chart2::XRegressionCurve > & xRegCurve )
286 uno::Reference< XServiceName > xServName( xRegCurve, uno::UNO_QUERY );
287 if( xServName.is() &&
288 xServName->getServiceName().equals(
289 C2U( "com.sun.star.chart2.MeanValueRegressionCurve" )))
290 return true;
291 return false;
294 // static
295 uno::Reference< chart2::XRegressionCurve >
296 RegressionCurveHelper::getMeanValueLine(
297 const uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
299 if( xRegCnt.is())
303 uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
304 xRegCnt->getRegressionCurves());
305 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
307 if( isMeanValueLine( aCurves[i] ))
308 return aCurves[i];
311 catch( Exception & ex )
313 ASSERT_EXCEPTION( ex );
317 return uno::Reference< chart2::XRegressionCurve >();
320 // static
321 void RegressionCurveHelper::addMeanValueLine(
322 uno::Reference< XRegressionCurveContainer > & xRegCnt,
323 const uno::Reference< XComponentContext > & xContext,
324 const uno::Reference< XPropertySet > & xSeriesProp )
326 if( !xRegCnt.is() ||
327 ::chart::RegressionCurveHelper::hasMeanValueLine( xRegCnt ) )
328 return;
330 // todo: use a valid context
331 uno::Reference< XRegressionCurve > xCurve( createMeanValueLine( xContext ));
332 xRegCnt->addRegressionCurve( xCurve );
334 if( xSeriesProp.is())
336 uno::Reference< XPropertySet > xProp( xCurve, uno::UNO_QUERY );
337 if( xProp.is())
339 xProp->setPropertyValue( C2U( "LineColor" ),
340 xSeriesProp->getPropertyValue( C2U( "Color" )));
345 // static
346 void RegressionCurveHelper::removeMeanValueLine(
347 Reference< XRegressionCurveContainer > & xRegCnt )
349 if( !xRegCnt.is())
350 return;
354 Sequence< Reference< XRegressionCurve > > aCurves(
355 xRegCnt->getRegressionCurves());
356 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
358 if( isMeanValueLine( aCurves[i] ))
360 xRegCnt->removeRegressionCurve( aCurves[i] );
361 // attention: the iterator i has become invalid now
363 // note: assume that there is only one mean-value curve
364 // to remove multiple mean-value curves remove the break
365 break;
369 catch( Exception & ex )
371 ASSERT_EXCEPTION( ex );
375 void RegressionCurveHelper::addRegressionCurve(
376 tRegressionType eType,
377 uno::Reference< XRegressionCurveContainer > & xRegCnt,
378 const uno::Reference< XComponentContext > & /* xContext */,
379 const uno::Reference< beans::XPropertySet >& xPropertySource,
380 const uno::Reference< beans::XPropertySet >& xEquationProperties )
382 if( !xRegCnt.is() )
383 return;
385 if( eType == REGRESSION_TYPE_NONE )
387 OSL_ENSURE(false,"don't create a regression curve of type none");
388 return;
391 uno::Reference< chart2::XRegressionCurve > xCurve;
392 ::rtl::OUString aServiceName( lcl_getServiceNameForType( eType ));
394 if( aServiceName.getLength())
396 // todo: use a valid context
397 xCurve.set( createRegressionCurveByServiceName(
398 uno::Reference< uno::XComponentContext >(), aServiceName ));
400 if( xEquationProperties.is())
401 xCurve->setEquationProperties( xEquationProperties );
403 uno::Reference< beans::XPropertySet > xProp( xCurve, uno::UNO_QUERY );
404 if( xProp.is())
406 if( xPropertySource.is())
407 comphelper::copyProperties( xPropertySource, xProp );
408 else
410 uno::Reference< XPropertySet > xSeriesProp( xRegCnt, uno::UNO_QUERY );
411 if( xSeriesProp.is())
413 xProp->setPropertyValue( C2U( "LineColor" ),
414 xSeriesProp->getPropertyValue( C2U( "Color" )));
416 // xProp->setPropertyValue( C2U( "LineWidth" ), uno::makeAny( sal_Int32( 100 )));
420 xRegCnt->addRegressionCurve( xCurve );
423 /** removes all regression curves that are not of type mean value
424 and returns true, if anything was removed
426 bool RegressionCurveHelper::removeAllExceptMeanValueLine(
427 uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
429 bool bRemovedSomething = false;
430 if( xRegCnt.is())
434 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
435 xRegCnt->getRegressionCurves());
436 ::std::vector< uno::Reference< chart2::XRegressionCurve > > aCurvesToDelete;
437 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
439 if( ! isMeanValueLine( aCurves[i] ))
441 aCurvesToDelete.push_back( aCurves[ i ] );
445 for( ::std::vector< uno::Reference< chart2::XRegressionCurve > >::const_iterator aIt = aCurvesToDelete.begin();
446 aIt != aCurvesToDelete.end(); ++aIt )
448 xRegCnt->removeRegressionCurve( *aIt );
449 bRemovedSomething = true;
452 catch( uno::Exception & ex )
454 ASSERT_EXCEPTION( ex );
457 return bRemovedSomething;
460 // static
461 void RegressionCurveHelper::replaceOrAddCurveAndReduceToOne(
462 tRegressionType eType,
463 uno::Reference< XRegressionCurveContainer > & xRegCnt,
464 const uno::Reference< XComponentContext > & xContext )
466 uno::Reference< chart2::XRegressionCurve > xRegressionCurve( getFirstCurveNotMeanValueLine( xRegCnt ));
467 if( ! xRegressionCurve.is())
468 RegressionCurveHelper::addRegressionCurve( eType, xRegCnt, xContext );
469 else
471 OUString aServiceName( lcl_getServiceNameForType( eType ));
472 if( aServiceName.getLength())
474 RegressionCurveHelper::removeAllExceptMeanValueLine( xRegCnt );
475 RegressionCurveHelper::addRegressionCurve(
476 eType, xRegCnt, xContext,
477 Reference< beans::XPropertySet >( xRegressionCurve, uno::UNO_QUERY ),
478 xRegressionCurve->getEquationProperties());
483 // static
484 uno::Reference< chart2::XRegressionCurve > RegressionCurveHelper::getFirstCurveNotMeanValueLine(
485 const Reference< XRegressionCurveContainer > & xRegCnt )
487 if( !xRegCnt.is())
488 return NULL;
492 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
493 xRegCnt->getRegressionCurves());
494 ::std::vector< uno::Reference< chart2::XRegressionCurve > > aCurvesToDelete;
495 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
497 if( ! isMeanValueLine( aCurves[i] ))
499 return aCurves[ i ];
503 catch( Exception & ex )
505 ASSERT_EXCEPTION( ex );
508 return NULL;
511 // static
512 RegressionCurveHelper::tRegressionType RegressionCurveHelper::getRegressionType(
513 const Reference< XRegressionCurve > & xCurve )
515 tRegressionType eResult = REGRESSION_TYPE_UNKNOWN;
519 Reference< lang::XServiceName > xServName( xCurve, uno::UNO_QUERY );
520 if( xServName.is())
522 ::rtl::OUString aServiceName( xServName->getServiceName() );
524 if( aServiceName.equalsAsciiL(
525 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LinearRegressionCurve" )))
527 eResult = REGRESSION_TYPE_LINEAR;
529 else if( aServiceName.equalsAsciiL(
530 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LogarithmicRegressionCurve" )))
532 eResult = REGRESSION_TYPE_LOG;
534 else if( aServiceName.equalsAsciiL(
535 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ExponentialRegressionCurve" )))
537 eResult = REGRESSION_TYPE_EXP;
539 else if( aServiceName.equalsAsciiL(
540 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.PotentialRegressionCurve" )))
542 eResult = REGRESSION_TYPE_POWER;
544 else if( aServiceName.equalsAsciiL(
545 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.MeanValueRegressionCurve" )))
547 eResult = REGRESSION_TYPE_MEAN_VALUE;
551 catch( Exception & ex )
553 ASSERT_EXCEPTION( ex );
556 return eResult;
559 // static
560 RegressionCurveHelper::tRegressionType RegressionCurveHelper::getFirstRegressTypeNotMeanValueLine(
561 const Reference< XRegressionCurveContainer > & xRegCnt )
563 tRegressionType eResult = REGRESSION_TYPE_NONE;
565 if( xRegCnt.is())
567 Sequence< Reference< XRegressionCurve > > aCurves(
568 xRegCnt->getRegressionCurves());
569 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
571 tRegressionType eType = getRegressionType( aCurves[i] );
572 if( eType != REGRESSION_TYPE_MEAN_VALUE &&
573 eType != REGRESSION_TYPE_UNKNOWN )
575 eResult = eType;
576 break;
581 return eResult;
584 OUString RegressionCurveHelper::getUINameForRegressionCurve( const Reference< XRegressionCurve >& xRegressionCurve )
586 OUString aResult;
587 Reference< lang::XServiceName > xServiceName( xRegressionCurve, uno::UNO_QUERY );
588 if( ! xServiceName.is())
589 return aResult;
591 OUString aServiceName( xServiceName->getServiceName());
592 if( aServiceName.equalsAsciiL(
593 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.MeanValueRegressionCurve" )))
595 OSL_ENSURE( false, "Meanvalue lines in legend not supported" );
596 aResult = OUString();
597 // aResult = ::chart::SchResId::getResString( STR_OBJECT_AVERAGE_LINE );
599 else if( aServiceName.equalsAsciiL(
600 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LinearRegressionCurve" )))
602 aResult = ::chart::SchResId::getResString( STR_REGRESSION_LINEAR );
604 else if( aServiceName.equalsAsciiL(
605 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.LogarithmicRegressionCurve" )))
607 aResult = ::chart::SchResId::getResString( STR_REGRESSION_LOG );
609 else if( aServiceName.equalsAsciiL(
610 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.ExponentialRegressionCurve" )))
612 aResult = ::chart::SchResId::getResString( STR_REGRESSION_EXP );
614 else if( aServiceName.equalsAsciiL(
615 RTL_CONSTASCII_STRINGPARAM( "com.sun.star.chart2.PotentialRegressionCurve" )))
617 aResult = ::chart::SchResId::getResString( STR_REGRESSION_POWER );
620 return aResult;
623 // static
624 ::std::vector< Reference< chart2::XRegressionCurve > >
625 RegressionCurveHelper::getAllRegressionCurvesNotMeanValueLine(
626 const Reference< chart2::XDiagram > & xDiagram )
628 ::std::vector< Reference< chart2::XRegressionCurve > > aResult;
629 ::std::vector< Reference< chart2::XDataSeries > > aSeries( DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
630 for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeries.begin());
631 aIt != aSeries.end(); ++aIt )
633 Reference< chart2::XRegressionCurveContainer > xCurveCnt( *aIt, uno::UNO_QUERY );
634 if( xCurveCnt.is())
636 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
637 xCurveCnt->getRegressionCurves());
638 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
640 if( ! isMeanValueLine( aCurves[i] ))
641 aResult.push_back( aCurves[i] );
646 return aResult;
649 // static
650 void RegressionCurveHelper::resetEquationPosition(
651 const Reference< chart2::XRegressionCurve > & xCurve )
653 if( xCurve.is())
657 const OUString aPosPropertyName( RTL_CONSTASCII_USTRINGPARAM( "RelativePosition" ));
658 Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties()); // since m233: , uno::UNO_SET_THROW );
659 if( xEqProp->getPropertyValue( aPosPropertyName ).hasValue())
660 xEqProp->setPropertyValue( aPosPropertyName, uno::Any());
662 catch( const uno::Exception & ex )
664 ASSERT_EXCEPTION( ex );
669 sal_Int32 RegressionCurveHelper::getRegressionCurveIndex(
670 const Reference< chart2::XRegressionCurveContainer > & xContainer,
671 const Reference< chart2::XRegressionCurve > & xCurve )
673 if( xContainer.is())
675 uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
676 xContainer->getRegressionCurves());
677 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
679 if( xCurve == aCurves[i] )
680 return i;
683 return -1;
686 //.............................................................................
687 } //namespace chart
688 //.............................................................................