Coverage Report

Created: 2026-10-14 09:33

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