1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
44 #include "PropertyHelper.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
;
63 OUString
lcl_getServiceNameForType( ::chart::RegressionCurveHelper::tRegressionType eType
)
65 OUString aServiceName
;
68 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_LINEAR
:
69 aServiceName
= C2U( "com.sun.star.chart2.LinearRegressionCurve" );
71 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_LOG
:
72 aServiceName
= C2U( "com.sun.star.chart2.LogarithmicRegressionCurve" );
74 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_EXP
:
75 aServiceName
= C2U( "com.sun.star.chart2.ExponentialRegressionCurve" );
77 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_POWER
:
78 aServiceName
= C2U( "com.sun.star.chart2.PotentialRegressionCurve" );
81 OSL_ENSURE(false,"unknown regression curve type - use linear instead");
82 aServiceName
= C2U( "com.sun.star.chart2.LinearRegressionCurve" );
87 } // anonymous namespace
89 //.............................................................................
92 //.............................................................................
95 Reference
< XRegressionCurve
> RegressionCurveHelper::createMeanValueLine(
96 const Reference
< XComponentContext
> & xContext
)
98 return Reference
< XRegressionCurve
>(
99 new MeanValueRegressionCurve( xContext
));
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" )))
114 new LinearRegressionCurve( xContext
));
116 else if( aServiceName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
117 "com.sun.star.chart2.LogarithmicRegressionCurve" )))
120 new LogarithmicRegressionCurve( xContext
));
122 else if( aServiceName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
123 "com.sun.star.chart2.ExponentialRegressionCurve" )))
126 new ExponentialRegressionCurve( xContext
));
128 else if( aServiceName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
129 "com.sun.star.chart2.PotentialRegressionCurve" )))
132 new PotentialRegressionCurve( xContext
));
138 // ------------------------------------------------------------
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());
177 void RegressionCurveHelper::initializeCurveCalculator(
178 const Reference
< XRegressionCurveCalculator
> & xOutCurveCalculator
,
179 const Reference
< data::XDataSource
> & xSource
,
180 bool bUseXValuesIfAvailable
/* = true */ )
182 if( ! (xOutCurveCalculator
.is() &&
186 Sequence
< double > aXValues
, aYValues
;
187 bool bXValuesFound
= false, bYValuesFound
= false;
189 Sequence
< Reference
< data::XLabeledDataSequence
> > aDataSeqs( xSource
->getDataSequences());
192 ! (bXValuesFound
&& bYValuesFound
) && i
<aDataSeqs
.getLength();
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
&&
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
&&
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
)
232 bXValuesFound
= true;
235 if( bXValuesFound
&& bYValuesFound
&&
236 aXValues
.getLength() > 0 &&
237 aYValues
.getLength() > 0 )
238 xOutCurveCalculator
->recalculateRegression( aXValues
, aYValues
);
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 // ----------------------------------------
258 bool RegressionCurveHelper::hasMeanValueLine(
259 const uno::Reference
< XRegressionCurveContainer
> & xRegCnt
)
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
] ))
274 catch( Exception
& ex
)
276 ASSERT_EXCEPTION( ex
);
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" )))
295 uno::Reference
< chart2::XRegressionCurve
>
296 RegressionCurveHelper::getMeanValueLine(
297 const uno::Reference
< chart2::XRegressionCurveContainer
> & xRegCnt
)
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
] ))
311 catch( Exception
& ex
)
313 ASSERT_EXCEPTION( ex
);
317 return uno::Reference
< chart2::XRegressionCurve
>();
321 void RegressionCurveHelper::addMeanValueLine(
322 uno::Reference
< XRegressionCurveContainer
> & xRegCnt
,
323 const uno::Reference
< XComponentContext
> & xContext
,
324 const uno::Reference
< XPropertySet
> & xSeriesProp
)
327 ::chart::RegressionCurveHelper::hasMeanValueLine( xRegCnt
) )
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
);
339 xProp
->setPropertyValue( C2U( "LineColor" ),
340 xSeriesProp
->getPropertyValue( C2U( "Color" )));
346 void RegressionCurveHelper::removeMeanValueLine(
347 Reference
< XRegressionCurveContainer
> & xRegCnt
)
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
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
)
385 if( eType
== REGRESSION_TYPE_NONE
)
387 OSL_ENSURE(false,"don't create a regression curve of type none");
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
);
406 if( xPropertySource
.is())
407 comphelper::copyProperties( xPropertySource
, xProp
);
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;
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
;
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
);
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());
484 uno::Reference
< chart2::XRegressionCurve
> RegressionCurveHelper::getFirstCurveNotMeanValueLine(
485 const Reference
< XRegressionCurveContainer
> & xRegCnt
)
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
] ))
503 catch( Exception
& ex
)
505 ASSERT_EXCEPTION( ex
);
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
);
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
);
560 RegressionCurveHelper::tRegressionType
RegressionCurveHelper::getFirstRegressTypeNotMeanValueLine(
561 const Reference
< XRegressionCurveContainer
> & xRegCnt
)
563 tRegressionType eResult
= REGRESSION_TYPE_NONE
;
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
)
584 OUString
RegressionCurveHelper::getUINameForRegressionCurve( const Reference
< XRegressionCurve
>& xRegressionCurve
)
587 Reference
< lang::XServiceName
> xServiceName( xRegressionCurve
, uno::UNO_QUERY
);
588 if( ! xServiceName
.is())
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
);
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
);
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
] );
650 void RegressionCurveHelper::resetEquationPosition(
651 const Reference
< chart2::XRegressionCurve
> & xCurve
)
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
)
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
] )
686 //.............................................................................
688 //.............................................................................