bump product version to 4.1.6.2
[LibreOffice.git] / chart2 / source / tools / RegressionCurveHelper.cxx
blob08228bc0961f5947928b8de37d862dd5fb358a2c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "RegressionCurveHelper.hxx"
21 #include "MeanValueRegressionCurveCalculator.hxx"
22 #include "LinearRegressionCurveCalculator.hxx"
23 #include "LogarithmicRegressionCurveCalculator.hxx"
24 #include "ExponentialRegressionCurveCalculator.hxx"
25 #include "PotentialRegressionCurveCalculator.hxx"
26 #include "CommonConverters.hxx"
27 #include "RegressionCurveModel.hxx"
28 #include "ChartTypeHelper.hxx"
29 #include "ChartModelHelper.hxx"
30 #include "macros.hxx"
31 #include "PropertyHelper.hxx"
32 #include "ResId.hxx"
33 #include "Strings.hrc"
34 #include "DiagramHelper.hxx"
35 #include <com/sun/star/chart2/XChartDocument.hpp>
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::chart2;
40 using ::com::sun::star::uno::Reference;
41 using ::com::sun::star::uno::Sequence;
42 using ::com::sun::star::uno::XComponentContext;
43 using ::com::sun::star::lang::XServiceName;
44 using ::com::sun::star::beans::XPropertySet;
45 using ::com::sun::star::uno::Exception;
47 namespace
49 OUString lcl_getServiceNameForType( ::chart::RegressionCurveHelper::tRegressionType eType )
51 OUString aServiceName;
52 switch( eType )
54 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_LINEAR:
55 aServiceName = "com.sun.star.chart2.LinearRegressionCurve";
56 break;
57 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_LOG:
58 aServiceName = "com.sun.star.chart2.LogarithmicRegressionCurve";
59 break;
60 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_EXP:
61 aServiceName = "com.sun.star.chart2.ExponentialRegressionCurve";
62 break;
63 case ::chart::RegressionCurveHelper::REGRESSION_TYPE_POWER:
64 aServiceName = "com.sun.star.chart2.PotentialRegressionCurve";
65 break;
66 default:
67 OSL_FAIL("unknown regression curve type - use linear instead");
68 aServiceName = "com.sun.star.chart2.LinearRegressionCurve";
69 break;
71 return aServiceName;
73 } // anonymous namespace
75 //.............................................................................
76 namespace chart
78 //.............................................................................
80 Reference< XRegressionCurve > RegressionCurveHelper::createMeanValueLine(
81 const Reference< XComponentContext > & xContext )
83 return Reference< XRegressionCurve >(
84 new MeanValueRegressionCurve( xContext ));
87 Reference< XRegressionCurve > RegressionCurveHelper::createRegressionCurveByServiceName(
88 const Reference< XComponentContext > & xContext,
89 OUString aServiceName )
91 Reference< XRegressionCurve > xResult;
93 // todo: use factory methods with service name
94 if( aServiceName == "com.sun.star.chart2.LinearRegressionCurve" )
96 xResult.set( new LinearRegressionCurve( xContext ) );
98 else if( aServiceName == "com.sun.star.chart2.LogarithmicRegressionCurve" )
100 xResult.set( new LogarithmicRegressionCurve( xContext ) );
102 else if( aServiceName == "com.sun.star.chart2.ExponentialRegressionCurve" )
104 xResult.set( new ExponentialRegressionCurve( xContext ) );
106 else if( aServiceName == "com.sun.star.chart2.PotentialRegressionCurve" )
108 xResult.set( new PotentialRegressionCurve( xContext ) );
111 return xResult;
114 // ------------------------------------------------------------
116 Reference< XRegressionCurveCalculator > RegressionCurveHelper::createRegressionCurveCalculatorByServiceName(
117 OUString aServiceName )
119 Reference< XRegressionCurveCalculator > xResult;
121 // todo: use factory methods with service name
122 if( aServiceName == "com.sun.star.chart2.MeanValueRegressionCurve" )
124 xResult.set( new MeanValueRegressionCurveCalculator() );
126 if( aServiceName == "com.sun.star.chart2.LinearRegressionCurve" )
128 xResult.set( new LinearRegressionCurveCalculator() );
130 else if( aServiceName == "com.sun.star.chart2.LogarithmicRegressionCurve" )
132 xResult.set( new LogarithmicRegressionCurveCalculator() );
134 else if( aServiceName == "com.sun.star.chart2.ExponentialRegressionCurve" )
136 xResult.set( new ExponentialRegressionCurveCalculator() );
138 else if( aServiceName == "com.sun.star.chart2.PotentialRegressionCurve" )
140 xResult.set( new PotentialRegressionCurveCalculator() );
143 return xResult;
146 void RegressionCurveHelper::initializeCurveCalculator(
147 const Reference< XRegressionCurveCalculator > & xOutCurveCalculator,
148 const Reference< data::XDataSource > & xSource,
149 bool bUseXValuesIfAvailable /* = true */ )
151 if( ! (xOutCurveCalculator.is() &&
152 xSource.is() ))
153 return;
155 Sequence< double > aXValues, aYValues;
156 bool bXValuesFound = false, bYValuesFound = false;
158 Sequence< Reference< data::XLabeledDataSequence > > aDataSeqs( xSource->getDataSequences());
159 sal_Int32 i = 0;
160 for( i=0;
161 ! (bXValuesFound && bYValuesFound) && i<aDataSeqs.getLength();
162 ++i )
166 Reference< data::XDataSequence > xSeq( aDataSeqs[i]->getValues());
167 Reference< XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
168 OUString aRole;
169 if( xProp->getPropertyValue( "Role" ) >>= aRole )
171 if( bUseXValuesIfAvailable && !bXValuesFound && aRole == "values-x" )
173 aXValues = DataSequenceToDoubleSequence( xSeq );
174 bXValuesFound = true;
176 else if( !bYValuesFound && aRole == "values-y" )
178 aYValues = DataSequenceToDoubleSequence( xSeq );
179 bYValuesFound = true;
183 catch( const Exception & ex )
185 ASSERT_EXCEPTION( ex );
189 if( ! bXValuesFound &&
190 bYValuesFound )
192 // initialize with 1, 2, ...
193 //first category (index 0) matches with real number 1.0
194 aXValues.realloc( aYValues.getLength());
195 for( i=0; i<aXValues.getLength(); ++i )
196 aXValues[i] = i+1;
197 bXValuesFound = true;
200 if( bXValuesFound && bYValuesFound &&
201 aXValues.getLength() > 0 &&
202 aYValues.getLength() > 0 )
203 xOutCurveCalculator->recalculateRegression( aXValues, aYValues );
206 void RegressionCurveHelper::initializeCurveCalculator(
207 const Reference< XRegressionCurveCalculator > & xOutCurveCalculator,
208 const Reference< XDataSeries > & xSeries,
209 const Reference< frame::XModel > & xModel )
211 sal_Int32 nAxisType = ChartTypeHelper::getAxisType(
212 ChartModelHelper::getChartTypeOfSeries( xModel, xSeries ), 0 ); // x-axis
214 initializeCurveCalculator( xOutCurveCalculator,
215 uno::Reference< data::XDataSource >( xSeries, uno::UNO_QUERY ),
216 (nAxisType == AxisType::REALNUMBER) );
219 // ----------------------------------------
221 bool RegressionCurveHelper::hasMeanValueLine(
222 const uno::Reference< XRegressionCurveContainer > & xRegCnt )
224 if( !xRegCnt.is())
225 return false;
229 uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
230 xRegCnt->getRegressionCurves());
231 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
233 if( isMeanValueLine( aCurves[i] ))
234 return true;
237 catch( const Exception & ex )
239 ASSERT_EXCEPTION( ex );
242 return false;
245 bool RegressionCurveHelper::isMeanValueLine(
246 const uno::Reference< chart2::XRegressionCurve > & xRegCurve )
248 uno::Reference< XServiceName > xServName( xRegCurve, uno::UNO_QUERY );
249 if( xServName.is() &&
250 xServName->getServiceName().equals(
251 "com.sun.star.chart2.MeanValueRegressionCurve"))
252 return true;
253 return false;
256 uno::Reference< chart2::XRegressionCurve >
257 RegressionCurveHelper::getMeanValueLine(
258 const uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
260 if( xRegCnt.is())
264 uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
265 xRegCnt->getRegressionCurves());
266 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
268 if( isMeanValueLine( aCurves[i] ))
269 return aCurves[i];
272 catch( const Exception & ex )
274 ASSERT_EXCEPTION( ex );
278 return uno::Reference< chart2::XRegressionCurve >();
281 void RegressionCurveHelper::addMeanValueLine(
282 uno::Reference< XRegressionCurveContainer > & xRegCnt,
283 const uno::Reference< XComponentContext > & xContext,
284 const uno::Reference< XPropertySet > & xSeriesProp )
286 if( !xRegCnt.is() ||
287 ::chart::RegressionCurveHelper::hasMeanValueLine( xRegCnt ) )
288 return;
290 // todo: use a valid context
291 uno::Reference< XRegressionCurve > xCurve( createMeanValueLine( xContext ));
292 xRegCnt->addRegressionCurve( xCurve );
294 if( xSeriesProp.is())
296 uno::Reference< XPropertySet > xProp( xCurve, uno::UNO_QUERY );
297 if( xProp.is())
299 xProp->setPropertyValue( "LineColor",
300 xSeriesProp->getPropertyValue( "Color"));
305 void RegressionCurveHelper::removeMeanValueLine(
306 Reference< XRegressionCurveContainer > & xRegCnt )
308 if( !xRegCnt.is())
309 return;
313 Sequence< Reference< XRegressionCurve > > aCurves(
314 xRegCnt->getRegressionCurves());
315 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
317 if( isMeanValueLine( aCurves[i] ))
319 xRegCnt->removeRegressionCurve( aCurves[i] );
320 // attention: the iterator i has become invalid now
322 // note: assume that there is only one mean-value curve
323 // to remove multiple mean-value curves remove the break
324 break;
328 catch( const Exception & ex )
330 ASSERT_EXCEPTION( ex );
334 void RegressionCurveHelper::addRegressionCurve(
335 tRegressionType eType,
336 uno::Reference< XRegressionCurveContainer > & xRegCnt,
337 const uno::Reference< XComponentContext > & /* xContext */,
338 const uno::Reference< beans::XPropertySet >& xPropertySource,
339 const uno::Reference< beans::XPropertySet >& xEquationProperties )
341 if( !xRegCnt.is() )
342 return;
344 if( eType == REGRESSION_TYPE_NONE )
346 OSL_FAIL("don't create a regression curve of type none");
347 return;
350 uno::Reference< chart2::XRegressionCurve > xCurve;
351 OUString aServiceName( lcl_getServiceNameForType( eType ));
353 if( !aServiceName.isEmpty())
355 // todo: use a valid context
356 xCurve.set( createRegressionCurveByServiceName(
357 uno::Reference< uno::XComponentContext >(), aServiceName ));
359 if( xEquationProperties.is())
360 xCurve->setEquationProperties( xEquationProperties );
362 uno::Reference< beans::XPropertySet > xProp( xCurve, uno::UNO_QUERY );
363 if( xProp.is())
365 if( xPropertySource.is())
366 comphelper::copyProperties( xPropertySource, xProp );
367 else
369 uno::Reference< XPropertySet > xSeriesProp( xRegCnt, uno::UNO_QUERY );
370 if( xSeriesProp.is())
372 xProp->setPropertyValue( "LineColor",
373 xSeriesProp->getPropertyValue( "Color"));
375 // xProp->setPropertyValue( "LineWidth", uno::makeAny( sal_Int32( 100 )));
379 xRegCnt->addRegressionCurve( xCurve );
382 /** removes all regression curves that are not of type mean value
383 and returns true, if anything was removed
385 bool RegressionCurveHelper::removeAllExceptMeanValueLine(
386 uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
388 bool bRemovedSomething = false;
389 if( xRegCnt.is())
393 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
394 xRegCnt->getRegressionCurves());
395 ::std::vector< uno::Reference< chart2::XRegressionCurve > > aCurvesToDelete;
396 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
398 if( ! isMeanValueLine( aCurves[i] ))
400 aCurvesToDelete.push_back( aCurves[ i ] );
404 for( ::std::vector< uno::Reference< chart2::XRegressionCurve > >::const_iterator aIt = aCurvesToDelete.begin();
405 aIt != aCurvesToDelete.end(); ++aIt )
407 xRegCnt->removeRegressionCurve( *aIt );
408 bRemovedSomething = true;
411 catch( const uno::Exception & ex )
413 ASSERT_EXCEPTION( ex );
416 return bRemovedSomething;
419 void RegressionCurveHelper::removeEquations(
420 uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
422 if( xRegCnt.is())
426 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
427 xRegCnt->getRegressionCurves());
428 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
430 if( !isMeanValueLine( aCurves[i] ) )
432 uno::Reference< chart2::XRegressionCurve > xRegCurve( aCurves[ i ] );
433 if( xRegCurve.is() )
435 uno::Reference< beans::XPropertySet > xEqProp( xRegCurve->getEquationProperties() ) ;
436 if( xEqProp.is())
438 xEqProp->setPropertyValue( "ShowEquation", uno::makeAny( false ));
439 xEqProp->setPropertyValue( "ShowCorrelationCoefficient", uno::makeAny( false ));
445 catch( const uno::Exception & ex )
447 ASSERT_EXCEPTION( ex );
452 void RegressionCurveHelper::replaceOrAddCurveAndReduceToOne(
453 tRegressionType eType,
454 uno::Reference< XRegressionCurveContainer > & xRegCnt,
455 const uno::Reference< XComponentContext > & xContext )
457 uno::Reference< chart2::XRegressionCurve > xRegressionCurve( getFirstCurveNotMeanValueLine( xRegCnt ));
458 if( ! xRegressionCurve.is())
459 RegressionCurveHelper::addRegressionCurve( eType, xRegCnt, xContext );
460 else
462 OUString aServiceName( lcl_getServiceNameForType( eType ));
463 if( !aServiceName.isEmpty())
465 RegressionCurveHelper::removeAllExceptMeanValueLine( xRegCnt );
466 RegressionCurveHelper::addRegressionCurve(
467 eType, xRegCnt, xContext,
468 Reference< beans::XPropertySet >( xRegressionCurve, uno::UNO_QUERY ),
469 xRegressionCurve->getEquationProperties());
474 uno::Reference< chart2::XRegressionCurve > RegressionCurveHelper::getFirstCurveNotMeanValueLine(
475 const Reference< XRegressionCurveContainer > & xRegCnt )
477 if( !xRegCnt.is())
478 return NULL;
482 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
483 xRegCnt->getRegressionCurves());
484 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
486 if( ! isMeanValueLine( aCurves[i] ))
488 return aCurves[ i ];
492 catch( const Exception & ex )
494 ASSERT_EXCEPTION( ex );
497 return NULL;
500 RegressionCurveHelper::tRegressionType RegressionCurveHelper::getRegressionType(
501 const Reference< XRegressionCurve > & xCurve )
503 tRegressionType eResult = REGRESSION_TYPE_UNKNOWN;
507 Reference< lang::XServiceName > xServName( xCurve, uno::UNO_QUERY );
508 if( xServName.is())
510 OUString aServiceName( xServName->getServiceName() );
512 if( aServiceName == "com.sun.star.chart2.LinearRegressionCurve" )
514 eResult = REGRESSION_TYPE_LINEAR;
516 else if( aServiceName == "com.sun.star.chart2.LogarithmicRegressionCurve" )
518 eResult = REGRESSION_TYPE_LOG;
520 else if( aServiceName == "com.sun.star.chart2.ExponentialRegressionCurve" )
522 eResult = REGRESSION_TYPE_EXP;
524 else if( aServiceName == "com.sun.star.chart2.PotentialRegressionCurve" )
526 eResult = REGRESSION_TYPE_POWER;
528 else if( aServiceName == "com.sun.star.chart2.MeanValueRegressionCurve" )
530 eResult = REGRESSION_TYPE_MEAN_VALUE;
534 catch( const Exception & ex )
536 ASSERT_EXCEPTION( ex );
539 return eResult;
542 RegressionCurveHelper::tRegressionType RegressionCurveHelper::getFirstRegressTypeNotMeanValueLine(
543 const Reference< XRegressionCurveContainer > & xRegCnt )
545 tRegressionType eResult = REGRESSION_TYPE_NONE;
547 if( xRegCnt.is())
549 Sequence< Reference< XRegressionCurve > > aCurves(
550 xRegCnt->getRegressionCurves());
551 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
553 tRegressionType eType = getRegressionType( aCurves[i] );
554 if( eType != REGRESSION_TYPE_MEAN_VALUE &&
555 eType != REGRESSION_TYPE_UNKNOWN )
557 eResult = eType;
558 break;
563 return eResult;
566 OUString RegressionCurveHelper::getUINameForRegressionCurve( const Reference< XRegressionCurve >& xRegressionCurve )
568 OUString aResult;
569 Reference< lang::XServiceName > xServiceName( xRegressionCurve, uno::UNO_QUERY );
570 if( ! xServiceName.is())
571 return aResult;
573 OUString aServiceName( xServiceName->getServiceName());
574 if( aServiceName == "com.sun.star.chart2.MeanValueRegressionCurve" )
576 aResult = SCH_RESSTR(STR_REGRESSION_MEAN);
578 else if( aServiceName == "com.sun.star.chart2.LinearRegressionCurve" )
580 aResult = SCH_RESSTR(STR_REGRESSION_LINEAR);
582 else if( aServiceName == "com.sun.star.chart2.LogarithmicRegressionCurve" )
584 aResult = SCH_RESSTR(STR_REGRESSION_LOG);
586 else if( aServiceName == "com.sun.star.chart2.ExponentialRegressionCurve" )
588 aResult = SCH_RESSTR(STR_REGRESSION_EXP);
590 else if( aServiceName == "com.sun.star.chart2.PotentialRegressionCurve" )
592 aResult = SCH_RESSTR(STR_REGRESSION_POWER);
595 return aResult;
598 ::std::vector< Reference< chart2::XRegressionCurve > >
599 RegressionCurveHelper::getAllRegressionCurvesNotMeanValueLine(
600 const Reference< chart2::XDiagram > & xDiagram )
602 ::std::vector< Reference< chart2::XRegressionCurve > > aResult;
603 ::std::vector< Reference< chart2::XDataSeries > > aSeries( DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
604 for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeries.begin());
605 aIt != aSeries.end(); ++aIt )
607 Reference< chart2::XRegressionCurveContainer > xCurveCnt( *aIt, uno::UNO_QUERY );
608 if( xCurveCnt.is())
610 uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
611 xCurveCnt->getRegressionCurves());
612 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
614 if( ! isMeanValueLine( aCurves[i] ))
615 aResult.push_back( aCurves[i] );
620 return aResult;
623 void RegressionCurveHelper::resetEquationPosition(
624 const Reference< chart2::XRegressionCurve > & xCurve )
626 if( xCurve.is())
630 const OUString aPosPropertyName( "RelativePosition" );
631 Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties()); // since m233: , uno::UNO_SET_THROW );
632 if( xEqProp->getPropertyValue( aPosPropertyName ).hasValue())
633 xEqProp->setPropertyValue( aPosPropertyName, uno::Any());
635 catch( const uno::Exception & ex )
637 ASSERT_EXCEPTION( ex );
642 sal_Int32 RegressionCurveHelper::getRegressionCurveIndex(
643 const Reference< chart2::XRegressionCurveContainer > & xContainer,
644 const Reference< chart2::XRegressionCurve > & xCurve )
646 if( xContainer.is())
648 uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
649 xContainer->getRegressionCurves());
650 for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
652 if( xCurve == aCurves[i] )
653 return i;
656 return -1;
659 bool RegressionCurveHelper::hasEquation( const Reference< chart2::XRegressionCurve > & xCurve )
661 bool bHasEquation = false;
662 if( xCurve.is())
664 uno::Reference< beans::XPropertySet > xEquationProp( xCurve->getEquationProperties());
665 if( xEquationProp.is())
667 bool bShowEquation = false;
668 bool bShowCoefficient = false;
669 xEquationProp->getPropertyValue( "ShowEquation") >>= bShowEquation;
670 xEquationProp->getPropertyValue( "ShowCorrelationCoefficient") >>= bShowCoefficient;
671 bHasEquation = bShowEquation || bShowCoefficient;
674 return bHasEquation;
677 //.............................................................................
678 } //namespace chart
679 //.............................................................................
681 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */