1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <RegressionCurveHelper.hxx>
21 #include <MeanValueRegressionCurveCalculator.hxx>
22 #include <LinearRegressionCurveCalculator.hxx>
23 #include <PolynomialRegressionCurveCalculator.hxx>
24 #include <MovingAverageRegressionCurveCalculator.hxx>
25 #include <LogarithmicRegressionCurveCalculator.hxx>
26 #include <ExponentialRegressionCurveCalculator.hxx>
27 #include <PotentialRegressionCurveCalculator.hxx>
28 #include <CommonConverters.hxx>
29 #include "RegressionCurveModel.hxx"
30 #include <ChartTypeHelper.hxx>
31 #include <ChartModelHelper.hxx>
32 #include <ResId.hxx>
33 #include <strings.hrc>
34 #include <DiagramHelper.hxx>
35 #include <com/sun/star/chart2/AxisType.hpp>
36 #include <com/sun/star/chart2/XRegressionCurveCalculator.hpp>
37 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
38 #include <tools/diagnose_ex.h>
39 #include <comphelper/property.hxx>
40 
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::chart2;
43 
44 using ::com::sun::star::uno::Reference;
45 using ::com::sun::star::uno::Sequence;
46 using ::com::sun::star::lang::XServiceName;
47 using ::com::sun::star::beans::XPropertySet;
48 using ::com::sun::star::uno::Exception;
49 
50 namespace
51 {
lcl_getServiceNameForType(SvxChartRegress eType)52 OUString lcl_getServiceNameForType(SvxChartRegress eType)
53 {
54     OUString aServiceName;
55     switch( eType )
56     {
57         case SvxChartRegress::Linear:
58             aServiceName = "com.sun.star.chart2.LinearRegressionCurve";
59             break;
60         case SvxChartRegress::Log:
61             aServiceName = "com.sun.star.chart2.LogarithmicRegressionCurve";
62             break;
63         case SvxChartRegress::Exp:
64             aServiceName = "com.sun.star.chart2.ExponentialRegressionCurve";
65             break;
66         case SvxChartRegress::Power:
67             aServiceName = "com.sun.star.chart2.PotentialRegressionCurve";
68             break;
69         case SvxChartRegress::Polynomial:
70             aServiceName = "com.sun.star.chart2.PolynomialRegressionCurve";
71             break;
72         case SvxChartRegress::MovingAverage:
73             aServiceName = "com.sun.star.chart2.MovingAverageRegressionCurve";
74             break;
75         default:
76             OSL_FAIL("unknown regression curve type - use linear instead");
77             aServiceName = "com.sun.star.chart2.LinearRegressionCurve";
78             break;
79     }
80     return aServiceName;
81 }
82 
83 } // anonymous namespace
84 
85 namespace chart
86 {
87 
createMeanValueLine()88 Reference< XRegressionCurve > RegressionCurveHelper::createMeanValueLine()
89 {
90     return Reference< XRegressionCurve >( new MeanValueRegressionCurve );
91 }
92 
createRegressionCurveByServiceName(std::u16string_view aServiceName)93 Reference< XRegressionCurve > RegressionCurveHelper::createRegressionCurveByServiceName(
94     std::u16string_view aServiceName )
95 {
96     Reference< XRegressionCurve > xResult;
97 
98     // todo: use factory methods with service name
99     if( aServiceName == u"com.sun.star.chart2.LinearRegressionCurve" )
100     {
101         xResult.set( new LinearRegressionCurve );
102     }
103     else if( aServiceName == u"com.sun.star.chart2.LogarithmicRegressionCurve" )
104     {
105         xResult.set( new LogarithmicRegressionCurve );
106     }
107     else if( aServiceName == u"com.sun.star.chart2.ExponentialRegressionCurve" )
108     {
109         xResult.set( new ExponentialRegressionCurve );
110     }
111     else if( aServiceName == u"com.sun.star.chart2.PotentialRegressionCurve" )
112     {
113         xResult.set( new PotentialRegressionCurve );
114     }
115     else if( aServiceName == u"com.sun.star.chart2.PolynomialRegressionCurve" )
116     {
117         xResult.set( new PolynomialRegressionCurve );
118     }
119     else if( aServiceName == u"com.sun.star.chart2.MovingAverageRegressionCurve" )
120     {
121         xResult.set( new MovingAverageRegressionCurve );
122     }
123 
124     return xResult;
125 }
126 
createRegressionCurveCalculatorByServiceName(std::u16string_view aServiceName)127 Reference< XRegressionCurveCalculator > RegressionCurveHelper::createRegressionCurveCalculatorByServiceName(
128     std::u16string_view aServiceName )
129 {
130     Reference< XRegressionCurveCalculator > xResult;
131 
132     // todo: use factory methods with service name
133     if( aServiceName == u"com.sun.star.chart2.MeanValueRegressionCurve" )
134     {
135         xResult.set( new MeanValueRegressionCurveCalculator() );
136     }
137     if( aServiceName == u"com.sun.star.chart2.LinearRegressionCurve" )
138     {
139         xResult.set( new LinearRegressionCurveCalculator() );
140     }
141     else if( aServiceName == u"com.sun.star.chart2.LogarithmicRegressionCurve" )
142     {
143         xResult.set( new LogarithmicRegressionCurveCalculator() );
144     }
145     else if( aServiceName == u"com.sun.star.chart2.ExponentialRegressionCurve" )
146     {
147         xResult.set( new ExponentialRegressionCurveCalculator() );
148     }
149     else if( aServiceName == u"com.sun.star.chart2.PotentialRegressionCurve" )
150     {
151         xResult.set( new PotentialRegressionCurveCalculator() );
152     }
153     else if( aServiceName == u"com.sun.star.chart2.PolynomialRegressionCurve" )
154     {
155         xResult.set( new PolynomialRegressionCurveCalculator() );
156     }
157     else if( aServiceName == u"com.sun.star.chart2.MovingAverageRegressionCurve" )
158     {
159         xResult.set( new MovingAverageRegressionCurveCalculator() );
160     }
161 
162     return xResult;
163 }
164 
initializeCurveCalculator(const Reference<XRegressionCurveCalculator> & xOutCurveCalculator,const Reference<data::XDataSource> & xSource,bool bUseXValuesIfAvailable)165 void RegressionCurveHelper::initializeCurveCalculator(
166     const Reference< XRegressionCurveCalculator > & xOutCurveCalculator,
167     const Reference< data::XDataSource > & xSource,
168     bool bUseXValuesIfAvailable /* = true */ )
169 {
170     if( ! (xOutCurveCalculator.is() &&
171            xSource.is() ))
172         return;
173 
174     Sequence< double > aXValues, aYValues;
175     bool bXValuesFound = false, bYValuesFound = false;
176 
177     Sequence< Reference< data::XLabeledDataSequence > > aDataSeqs( xSource->getDataSequences());
178     sal_Int32 i = 0;
179     for( i=0;
180          ! (bXValuesFound && bYValuesFound) && i<aDataSeqs.getLength();
181          ++i )
182     {
183         try
184         {
185             Reference< data::XDataSequence > xSeq( aDataSeqs[i]->getValues());
186             Reference< XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW );
187             OUString aRole;
188             if( xProp->getPropertyValue( "Role" ) >>= aRole )
189             {
190                 if( bUseXValuesIfAvailable && !bXValuesFound && aRole == "values-x" )
191                 {
192                     aXValues = DataSequenceToDoubleSequence( xSeq );
193                     bXValuesFound = true;
194                 }
195                 else if( !bYValuesFound && aRole == "values-y" )
196                 {
197                     aYValues = DataSequenceToDoubleSequence( xSeq );
198                     bYValuesFound = true;
199                 }
200             }
201         }
202         catch( const Exception & )
203         {
204             DBG_UNHANDLED_EXCEPTION("chart2");
205         }
206     }
207 
208     if( ! bXValuesFound &&
209         bYValuesFound )
210     {
211         // initialize with 1, 2, ...
212         //first category (index 0) matches with real number 1.0
213         aXValues.realloc( aYValues.getLength());
214         for( i=0; i<aXValues.getLength(); ++i )
215             aXValues[i] = i+1;
216         bXValuesFound = true;
217     }
218 
219     if( bXValuesFound && bYValuesFound &&
220         aXValues.hasElements() &&
221         aYValues.hasElements() )
222         xOutCurveCalculator->recalculateRegression( aXValues, aYValues );
223 }
224 
initializeCurveCalculator(const Reference<XRegressionCurveCalculator> & xOutCurveCalculator,const Reference<XDataSeries> & xSeries,const Reference<frame::XModel> & xModel)225 void RegressionCurveHelper::initializeCurveCalculator(
226     const Reference< XRegressionCurveCalculator > & xOutCurveCalculator,
227     const Reference< XDataSeries > & xSeries,
228     const Reference< frame::XModel > & xModel )
229 {
230     sal_Int32 nAxisType = ChartTypeHelper::getAxisType(
231         ChartModelHelper::getChartTypeOfSeries( xModel, xSeries ), 0 ); // x-axis
232 
233     initializeCurveCalculator( xOutCurveCalculator,
234                                uno::Reference< data::XDataSource >( xSeries, uno::UNO_QUERY ),
235                                (nAxisType == AxisType::REALNUMBER) );
236 }
237 
hasMeanValueLine(const uno::Reference<XRegressionCurveContainer> & xRegCnt)238 bool RegressionCurveHelper::hasMeanValueLine(
239     const uno::Reference< XRegressionCurveContainer > & xRegCnt )
240 {
241     if( !xRegCnt.is())
242         return false;
243 
244     try
245     {
246         const uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
247             xRegCnt->getRegressionCurves());
248         for( uno::Reference< XRegressionCurve > const & curve : aCurves )
249         {
250             if( isMeanValueLine( curve ))
251                 return true;
252         }
253     }
254     catch( const Exception & )
255     {
256         DBG_UNHANDLED_EXCEPTION("chart2");
257     }
258 
259     return false;
260 }
261 
isMeanValueLine(const uno::Reference<chart2::XRegressionCurve> & xRegCurve)262 bool RegressionCurveHelper::isMeanValueLine(
263     const uno::Reference< chart2::XRegressionCurve > & xRegCurve )
264 {
265     uno::Reference< XServiceName > xServName( xRegCurve, uno::UNO_QUERY );
266     return xServName.is() &&
267         xServName->getServiceName() ==
268             "com.sun.star.chart2.MeanValueRegressionCurve";
269 }
270 
271 uno::Reference< chart2::XRegressionCurve >
getMeanValueLine(const uno::Reference<chart2::XRegressionCurveContainer> & xRegCnt)272     RegressionCurveHelper::getMeanValueLine(
273         const uno::Reference< chart2::XRegressionCurveContainer > & xRegCnt )
274 {
275     if( xRegCnt.is())
276     {
277         try
278         {
279             const uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
280                 xRegCnt->getRegressionCurves());
281             for( uno::Reference< XRegressionCurve > const & curve : aCurves )
282             {
283                 if( isMeanValueLine( curve ))
284                     return curve;
285             }
286         }
287         catch( const Exception & )
288         {
289             DBG_UNHANDLED_EXCEPTION("chart2");
290         }
291     }
292 
293     return uno::Reference< chart2::XRegressionCurve >();
294 }
295 
addMeanValueLine(uno::Reference<XRegressionCurveContainer> const & xRegCnt,const uno::Reference<XPropertySet> & xSeriesProp)296 void RegressionCurveHelper::addMeanValueLine(
297     uno::Reference< XRegressionCurveContainer > const & xRegCnt,
298     const uno::Reference< XPropertySet > & xSeriesProp )
299 {
300     if( !xRegCnt.is() ||
301         ::chart::RegressionCurveHelper::hasMeanValueLine( xRegCnt ) )
302         return;
303 
304     // todo: use a valid context
305     uno::Reference< XRegressionCurve > xCurve( createMeanValueLine() );
306     xRegCnt->addRegressionCurve( xCurve );
307 
308     if( xSeriesProp.is())
309     {
310         uno::Reference< XPropertySet > xProp( xCurve, uno::UNO_QUERY );
311         if( xProp.is())
312         {
313             xProp->setPropertyValue( "LineColor",
314                                      xSeriesProp->getPropertyValue( "Color"));
315         }
316     }
317 }
318 
removeMeanValueLine(Reference<XRegressionCurveContainer> const & xRegCnt)319 void RegressionCurveHelper::removeMeanValueLine(
320     Reference< XRegressionCurveContainer > const & xRegCnt )
321 {
322     if( !xRegCnt.is())
323         return;
324 
325     try
326     {
327         const Sequence< Reference< XRegressionCurve > > aCurves(
328             xRegCnt->getRegressionCurves());
329         for( Reference< XRegressionCurve > const & curve : aCurves )
330         {
331             if( isMeanValueLine( curve ))
332             {
333                 xRegCnt->removeRegressionCurve( curve );
334                 // attention: the iterator i has become invalid now
335 
336                 // note: assume that there is only one mean-value curve
337                 // to remove multiple mean-value curves remove the break
338                 break;
339             }
340         }
341     }
342     catch( const Exception & )
343     {
344         DBG_UNHANDLED_EXCEPTION("chart2");
345     }
346 }
347 
addRegressionCurve(SvxChartRegress eType,uno::Reference<XRegressionCurveContainer> const & xRegressionCurveContainer,const uno::Reference<beans::XPropertySet> & xPropertySource,const uno::Reference<beans::XPropertySet> & xEquationProperties)348 uno::Reference< chart2::XRegressionCurve > RegressionCurveHelper::addRegressionCurve(
349     SvxChartRegress eType,
350     uno::Reference< XRegressionCurveContainer > const & xRegressionCurveContainer,
351     const uno::Reference< beans::XPropertySet >& xPropertySource,
352     const uno::Reference< beans::XPropertySet >& xEquationProperties )
353 {
354     uno::Reference< chart2::XRegressionCurve > xCurve;
355 
356     if( !xRegressionCurveContainer.is() )
357         return xCurve;
358 
359     if( eType == SvxChartRegress::NONE )
360     {
361         OSL_FAIL("don't create a regression curve of type none");
362         return xCurve;
363     }
364 
365     OUString aServiceName( lcl_getServiceNameForType( eType ));
366     if( !aServiceName.isEmpty())
367     {
368         // todo: use a valid context
369         xCurve.set( createRegressionCurveByServiceName( aServiceName ) );
370 
371         if( xEquationProperties.is())
372             xCurve->setEquationProperties( xEquationProperties );
373 
374         uno::Reference< beans::XPropertySet > xProperties( xCurve, uno::UNO_QUERY );
375         if( xProperties.is())
376         {
377             if( xPropertySource.is())
378                 comphelper::copyProperties( xPropertySource, xProperties );
379             else
380             {
381                 uno::Reference< XPropertySet > xSeriesProp( xRegressionCurveContainer, uno::UNO_QUERY );
382                 if( xSeriesProp.is())
383                 {
384                     xProperties->setPropertyValue( "LineColor",
385                                              xSeriesProp->getPropertyValue( "Color"));
386                 }
387             }
388         }
389     }
390     xRegressionCurveContainer->addRegressionCurve( xCurve );
391 
392     return xCurve;
393 }
394 
395 /** removes all regression curves that are not of type mean value
396     and returns true, if anything was removed
397  */
removeAllExceptMeanValueLine(uno::Reference<chart2::XRegressionCurveContainer> const & xRegCnt)398 bool RegressionCurveHelper::removeAllExceptMeanValueLine(
399     uno::Reference< chart2::XRegressionCurveContainer > const & xRegCnt )
400 {
401     bool bRemovedSomething = false;
402     if( xRegCnt.is())
403     {
404         try
405         {
406             const uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
407                 xRegCnt->getRegressionCurves());
408             std::vector< uno::Reference< chart2::XRegressionCurve > > aCurvesToDelete;
409             for( uno::Reference< chart2::XRegressionCurve > const & curve : aCurves )
410             {
411                 if( ! isMeanValueLine( curve ))
412                 {
413                     aCurvesToDelete.push_back( curve );
414                 }
415             }
416 
417             for (auto const& curveToDelete : aCurvesToDelete)
418             {
419                 xRegCnt->removeRegressionCurve(curveToDelete);
420                 bRemovedSomething = true;
421             }
422         }
423         catch( const uno::Exception & )
424         {
425             DBG_UNHANDLED_EXCEPTION("chart2");
426         }
427     }
428     return bRemovedSomething;
429 }
430 
removeEquations(uno::Reference<chart2::XRegressionCurveContainer> const & xRegCnt)431 void RegressionCurveHelper::removeEquations(
432         uno::Reference< chart2::XRegressionCurveContainer > const & xRegCnt )
433 {
434     if( !xRegCnt.is())
435         return;
436 
437     try
438     {
439         const uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
440             xRegCnt->getRegressionCurves());
441         for( uno::Reference< chart2::XRegressionCurve >  const & curve : aCurves )
442         {
443             if( !isMeanValueLine( curve ) )
444             {
445                 uno::Reference< chart2::XRegressionCurve > xRegCurve( curve );
446                 if( xRegCurve.is() )
447                 {
448                     uno::Reference< beans::XPropertySet > xEqProp( xRegCurve->getEquationProperties() ) ;
449                     if( xEqProp.is())
450                     {
451                         xEqProp->setPropertyValue( "ShowEquation", uno::Any( false ));
452                         xEqProp->setPropertyValue( "XName", uno::Any( OUString("x") ));
453                         xEqProp->setPropertyValue( "YName", uno::Any( OUString("f(x) ") ));
454                         xEqProp->setPropertyValue( "ShowCorrelationCoefficient", uno::Any( false ));
455                     }
456                 }
457             }
458         }
459     }
460     catch( const uno::Exception & )
461     {
462         DBG_UNHANDLED_EXCEPTION("chart2");
463     }
464 }
465 
changeRegressionCurveType(SvxChartRegress eType,uno::Reference<XRegressionCurveContainer> const & xRegressionCurveContainer,uno::Reference<XRegressionCurve> const & xRegressionCurve)466 uno::Reference< XRegressionCurve > RegressionCurveHelper::changeRegressionCurveType(
467     SvxChartRegress eType,
468     uno::Reference< XRegressionCurveContainer > const & xRegressionCurveContainer,
469     uno::Reference< XRegressionCurve > const & xRegressionCurve )
470 {
471     xRegressionCurveContainer->removeRegressionCurve( xRegressionCurve );
472     return RegressionCurveHelper::addRegressionCurve(
473             eType,
474             xRegressionCurveContainer,
475             uno::Reference< beans::XPropertySet >( xRegressionCurve, uno::UNO_QUERY ),
476             xRegressionCurve->getEquationProperties());
477 }
478 
getFirstCurveNotMeanValueLine(const Reference<XRegressionCurveContainer> & xRegCnt)479 uno::Reference< chart2::XRegressionCurve > RegressionCurveHelper::getFirstCurveNotMeanValueLine(
480     const Reference< XRegressionCurveContainer > & xRegCnt )
481 {
482     if( !xRegCnt.is())
483         return nullptr;
484 
485     try
486     {
487         const uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(
488             xRegCnt->getRegressionCurves());
489         for( uno::Reference< chart2::XRegressionCurve > const & curve : aCurves )
490         {
491             if( ! isMeanValueLine( curve ))
492             {
493                 return curve;
494             }
495         }
496     }
497     catch( const Exception & )
498     {
499         DBG_UNHANDLED_EXCEPTION("chart2");
500     }
501 
502     return nullptr;
503 }
504 
getRegressionCurveAtIndex(const Reference<XRegressionCurveContainer> & xCurveContainer,sal_Int32 aIndex)505 uno::Reference< chart2::XRegressionCurve > RegressionCurveHelper::getRegressionCurveAtIndex(
506     const Reference< XRegressionCurveContainer >& xCurveContainer,
507     sal_Int32 aIndex )
508 {
509     if( !xCurveContainer.is())
510         return nullptr;
511 
512     try
513     {
514         uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(xCurveContainer->getRegressionCurves());
515         if(0 <= aIndex && aIndex < aCurves.getLength())
516         {
517             if(!isMeanValueLine(aCurves[aIndex]))
518                 return aCurves[aIndex];
519         }
520     }
521     catch( const Exception & )
522     {
523         DBG_UNHANDLED_EXCEPTION("chart2");
524     }
525 
526     return nullptr;
527 }
528 
getRegressionType(const Reference<XRegressionCurve> & xCurve)529 SvxChartRegress RegressionCurveHelper::getRegressionType(
530     const Reference< XRegressionCurve > & xCurve )
531 {
532     SvxChartRegress eResult = SvxChartRegress::Unknown;
533 
534     try
535     {
536         Reference< lang::XServiceName > xServName( xCurve, uno::UNO_QUERY );
537         if( xServName.is())
538         {
539             OUString aServiceName( xServName->getServiceName() );
540 
541             if( aServiceName == "com.sun.star.chart2.LinearRegressionCurve" )
542             {
543                 eResult = SvxChartRegress::Linear;
544             }
545             else if( aServiceName == "com.sun.star.chart2.LogarithmicRegressionCurve" )
546             {
547                 eResult = SvxChartRegress::Log;
548             }
549             else if( aServiceName == "com.sun.star.chart2.ExponentialRegressionCurve" )
550             {
551                 eResult = SvxChartRegress::Exp;
552             }
553             else if( aServiceName == "com.sun.star.chart2.PotentialRegressionCurve" )
554             {
555                 eResult = SvxChartRegress::Power;
556             }
557             else if( aServiceName == "com.sun.star.chart2.MeanValueRegressionCurve" )
558             {
559                 eResult = SvxChartRegress::MeanValue;
560             }
561             else if( aServiceName == "com.sun.star.chart2.PolynomialRegressionCurve" )
562             {
563                 eResult = SvxChartRegress::Polynomial;
564             }
565             else if( aServiceName == "com.sun.star.chart2.MovingAverageRegressionCurve" )
566             {
567                 eResult = SvxChartRegress::MovingAverage;
568             }
569         }
570     }
571     catch( const Exception & )
572     {
573         DBG_UNHANDLED_EXCEPTION("chart2" );
574     }
575 
576     return eResult;
577 }
578 
getFirstRegressTypeNotMeanValueLine(const Reference<XRegressionCurveContainer> & xRegCnt)579 SvxChartRegress RegressionCurveHelper::getFirstRegressTypeNotMeanValueLine(
580     const Reference< XRegressionCurveContainer > & xRegCnt )
581 {
582     SvxChartRegress eResult = SvxChartRegress::NONE;
583 
584     if( xRegCnt.is())
585     {
586         const Sequence< Reference< XRegressionCurve > > aCurves(
587             xRegCnt->getRegressionCurves());
588         for( Reference< XRegressionCurve > const & curve : aCurves )
589         {
590             SvxChartRegress eType = getRegressionType( curve );
591             if( eType != SvxChartRegress::MeanValue &&
592                 eType != SvxChartRegress::Unknown )
593             {
594                 eResult = eType;
595                 break;
596             }
597         }
598     }
599 
600     return eResult;
601 }
602 
getUINameForRegressionCurve(const Reference<XRegressionCurve> & xRegressionCurve)603 OUString RegressionCurveHelper::getUINameForRegressionCurve( const Reference< XRegressionCurve >& xRegressionCurve )
604 {
605     OUString aResult = getRegressionCurveSpecificName(xRegressionCurve);
606     if (aResult.isEmpty())
607     {
608         aResult = getRegressionCurveGenericName(xRegressionCurve);
609         if (!aResult.isEmpty())
610         {
611             aResult += " (%SERIESNAME)";
612         }
613     }
614     return aResult;
615 }
616 
getRegressionCurveGenericName(const Reference<XRegressionCurve> & xRegressionCurve)617 OUString RegressionCurveHelper::getRegressionCurveGenericName(const Reference< XRegressionCurve >& xRegressionCurve)
618 {
619     OUString aResult;
620     if(!xRegressionCurve.is())
621         return aResult;
622 
623     Reference< lang::XServiceName > xServiceName( xRegressionCurve, uno::UNO_QUERY );
624     if(!xServiceName.is())
625         return aResult;
626 
627     OUString aServiceName(xServiceName->getServiceName());
628 
629     if( aServiceName == "com.sun.star.chart2.MeanValueRegressionCurve" )
630     {
631         aResult = SchResId(STR_REGRESSION_MEAN);
632     }
633     else if( aServiceName == "com.sun.star.chart2.LinearRegressionCurve" )
634     {
635         aResult = SchResId(STR_REGRESSION_LINEAR);
636     }
637     else if( aServiceName == "com.sun.star.chart2.LogarithmicRegressionCurve" )
638     {
639         aResult = SchResId(STR_REGRESSION_LOG);
640     }
641     else if( aServiceName == "com.sun.star.chart2.ExponentialRegressionCurve" )
642     {
643         aResult = SchResId(STR_REGRESSION_EXP);
644     }
645     else if( aServiceName == "com.sun.star.chart2.PotentialRegressionCurve" )
646     {
647         aResult = SchResId(STR_REGRESSION_POWER);
648     }
649     else if( aServiceName == "com.sun.star.chart2.PolynomialRegressionCurve" )
650     {
651         aResult = SchResId(STR_REGRESSION_POLYNOMIAL);
652     }
653     else if( aServiceName == "com.sun.star.chart2.MovingAverageRegressionCurve" )
654     {
655         aResult = SchResId(STR_REGRESSION_MOVING_AVERAGE);
656     }
657     return aResult;
658 }
659 
getRegressionCurveSpecificName(const Reference<XRegressionCurve> & xRegressionCurve)660 OUString RegressionCurveHelper::getRegressionCurveSpecificName(const Reference< XRegressionCurve >& xRegressionCurve)
661 {
662     OUString aResult;
663 
664     if(!xRegressionCurve.is())
665         return aResult;
666 
667     Reference<XPropertySet> xProperties( xRegressionCurve, uno::UNO_QUERY );
668     if(!xProperties.is())
669         return aResult;
670 
671     xProperties->getPropertyValue("CurveName") >>= aResult;
672 
673     return aResult;
674 }
675 
getRegressionCurveName(const Reference<XRegressionCurve> & xRegressionCurve)676 OUString RegressionCurveHelper::getRegressionCurveName( const Reference< XRegressionCurve >& xRegressionCurve )
677 {
678     OUString aResult = getRegressionCurveSpecificName(xRegressionCurve);
679     if (aResult.isEmpty())
680         return getRegressionCurveGenericName(xRegressionCurve);
681     return aResult;
682 }
683 
684 std::vector< Reference< chart2::XRegressionCurve > >
getAllRegressionCurvesNotMeanValueLine(const Reference<chart2::XDiagram> & xDiagram)685     RegressionCurveHelper::getAllRegressionCurvesNotMeanValueLine(
686         const Reference< chart2::XDiagram > & xDiagram )
687 {
688     std::vector< Reference< chart2::XRegressionCurve > > aResult;
689     std::vector< Reference< chart2::XDataSeries > > aSeries( DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
690     for (auto const& elem : aSeries)
691     {
692         Reference< chart2::XRegressionCurveContainer > xContainer(elem, uno::UNO_QUERY);
693         if(xContainer.is())
694         {
695             const uno::Sequence< uno::Reference< chart2::XRegressionCurve > > aCurves(xContainer->getRegressionCurves());
696             for( Reference< XRegressionCurve > const & curve : aCurves )
697             {
698                 if( ! isMeanValueLine( curve ))
699                     aResult.push_back( curve );
700             }
701         }
702     }
703 
704     return aResult;
705 }
706 
resetEquationPosition(const Reference<chart2::XRegressionCurve> & xCurve)707 void RegressionCurveHelper::resetEquationPosition(
708     const Reference< chart2::XRegressionCurve > & xCurve )
709 {
710     if( !xCurve.is())
711         return;
712 
713     try
714     {
715         static const OUStringLiteral aPosPropertyName( u"RelativePosition" );
716         Reference< beans::XPropertySet > xEqProp( xCurve->getEquationProperties()); // since m233: , uno::UNO_SET_THROW );
717         if( xEqProp->getPropertyValue( aPosPropertyName ).hasValue())
718             xEqProp->setPropertyValue( aPosPropertyName, uno::Any());
719     }
720     catch( const uno::Exception & )
721     {
722         DBG_UNHANDLED_EXCEPTION("chart2" );
723     }
724 }
725 
getRegressionCurveIndex(const Reference<chart2::XRegressionCurveContainer> & xContainer,const Reference<chart2::XRegressionCurve> & xCurve)726 sal_Int32 RegressionCurveHelper::getRegressionCurveIndex(
727     const Reference< chart2::XRegressionCurveContainer >& xContainer,
728     const Reference< chart2::XRegressionCurve >& xCurve )
729 {
730     if( xContainer.is())
731     {
732         uno::Sequence< uno::Reference< XRegressionCurve > > aCurves(
733             xContainer->getRegressionCurves());
734 
735         for( sal_Int32 i = 0; i < aCurves.getLength(); ++i )
736         {
737             if( xCurve == aCurves[i] )
738                 return i;
739         }
740     }
741     return -1;
742 }
743 
hasEquation(const Reference<chart2::XRegressionCurve> & xCurve)744 bool RegressionCurveHelper::hasEquation( const Reference< chart2::XRegressionCurve > & xCurve )
745 {
746     bool bHasEquation = false;
747     if( xCurve.is())
748     {
749         uno::Reference< beans::XPropertySet > xEquationProp( xCurve->getEquationProperties());
750         if( xEquationProp.is())
751         {
752             bool bShowEquation = false;
753             bool bShowCoefficient = false;
754             xEquationProp->getPropertyValue( "ShowEquation") >>= bShowEquation;
755             xEquationProp->getPropertyValue( "ShowCorrelationCoefficient") >>= bShowCoefficient;
756             bHasEquation = bShowEquation || bShowCoefficient;
757         }
758     }
759     return bHasEquation;
760 }
761 
762 } //namespace chart
763 
764 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
765