/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: */ |