LibreOffice Module chart2 (master) 1
ErrorBarItemConverter.cxx
Go to the documentation of this file.
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
21#include "SchWhichPairs.hxx"
22#include <StatisticsHelper.hxx>
23
25
26#include <svl/stritem.hxx>
27#include <svx/chrtitem.hxx>
28#include <rtl/math.hxx>
29
30#include <com/sun/star/chart2/XInternalDataProvider.hpp>
31#include <com/sun/star/chart2/XChartDocument.hpp>
32#include <com/sun/star/chart/ErrorBarStyle.hpp>
33#include <utility>
35
36using namespace ::com::sun::star;
37
38namespace
39{
40
41void lcl_getErrorValues( const uno::Reference< beans::XPropertySet > & xErrorBarProp,
42 double & rOutPosError, double & rOutNegError )
43{
44 if( ! xErrorBarProp.is())
45 return;
46
47 try
48 {
49 xErrorBarProp->getPropertyValue( "PositiveError" ) >>= rOutPosError;
50 xErrorBarProp->getPropertyValue( "NegativeError" ) >>= rOutNegError;
51 }
52 catch( const uno::Exception & )
53 {
55 }
56}
57
58void lcl_getErrorIndicatorValues(
59 const uno::Reference< beans::XPropertySet > & xErrorBarProp,
60 bool & rOutShowPosError, bool & rOutShowNegError )
61{
62 if( ! xErrorBarProp.is())
63 return;
64
65 try
66 {
67 xErrorBarProp->getPropertyValue( "ShowPositiveError" ) >>= rOutShowPosError;
68 xErrorBarProp->getPropertyValue( "ShowNegativeError" ) >>= rOutShowNegError;
69 }
70 catch( const uno::Exception & )
71 {
73 }
74}
75
76} // anonymous namespace
77
78namespace chart::wrapper
79{
80
83 const uno::Reference< beans::XPropertySet > & rPropertySet,
84 SfxItemPool& rItemPool,
85 SdrModel& rDrawModel,
86 const uno::Reference< lang::XMultiServiceFactory > & xNamedPropertyContainerFactory ) :
87 ItemConverter( rPropertySet, rItemPool ),
88 m_spGraphicConverter( std::make_shared<GraphicPropertyItemConverter>(
89 rPropertySet, rItemPool, rDrawModel,
90 xNamedPropertyContainerFactory,
92 m_xModel(std::move( xModel ))
93{}
94
96{}
97
99{
100 m_spGraphicConverter->FillItemSet( rOutItemSet );
101
102 // own items
103 ItemConverter::FillItemSet( rOutItemSet );
104}
105
107{
108 bool bResult = m_spGraphicConverter->ApplyItemSet( rItemSet );
109
110 // own items
111 return ItemConverter::ApplyItemSet( rItemSet ) || bResult;
112}
113
115{
116 // must span all used items!
117 return nErrorBarWhichPairs;
118}
119
121 tWhichIdType /* nWhichId */,
122 tPropertyNameWithMemberId & /* rOutProperty */ ) const
123{
124 return false;
125}
126
128 sal_uInt16 nWhichId, const SfxItemSet & rItemSet )
129{
130 bool bChanged = false;
131
132 switch( nWhichId )
133 {
134 // Attention !!! This case must be passed before SCHATTR_STAT_PERCENT,
135 // SCHATTR_STAT_BIGERROR, SCHATTR_STAT_CONSTPLUS,
136 // SCHATTR_STAT_CONSTMINUS and SCHATTR_STAT_INDICATE
138 {
140
141 SvxChartKindError eErrorKind =
142 static_cast< const SvxChartKindErrorItem & >(
143 rItemSet.Get( nWhichId )).GetValue();
144
145 if( !xErrorBarProp.is() && eErrorKind == SvxChartKindError::NONE)
146 {
147 //nothing to do
148 }
149 else
150 {
151 sal_Int32 nStyle = css::chart::ErrorBarStyle::NONE;
152
153 switch( eErrorKind )
154 {
155 case SvxChartKindError::NONE:
156 nStyle = css::chart::ErrorBarStyle::NONE; break;
157 case SvxChartKindError::Variant:
158 nStyle = css::chart::ErrorBarStyle::VARIANCE; break;
159 case SvxChartKindError::Sigma:
160 nStyle = css::chart::ErrorBarStyle::STANDARD_DEVIATION; break;
161 case SvxChartKindError::Percent:
162 nStyle = css::chart::ErrorBarStyle::RELATIVE; break;
163 case SvxChartKindError::BigError:
164 nStyle = css::chart::ErrorBarStyle::ERROR_MARGIN; break;
165 case SvxChartKindError::Const:
166 nStyle = css::chart::ErrorBarStyle::ABSOLUTE; break;
167 case SvxChartKindError::StdError:
168 nStyle = css::chart::ErrorBarStyle::STANDARD_ERROR; break;
169 case SvxChartKindError::Range:
170 nStyle = css::chart::ErrorBarStyle::FROM_DATA; break;
171 }
172
173 xErrorBarProp->setPropertyValue( "ErrorBarStyle" , uno::Any( nStyle ));
174 bChanged = true;
175 }
176 }
177 break;
178
181 {
182 OSL_FAIL( "Deprecated item" );
184
185 double fValue =
186 static_cast< const SvxDoubleItem & >(
187 rItemSet.Get( nWhichId )).GetValue();
188 double fPos(0.0), fNeg(0.0);
189 lcl_getErrorValues( xErrorBarProp, fPos, fNeg );
190
191 if( ! ( ::rtl::math::approxEqual( fPos, fValue ) &&
192 ::rtl::math::approxEqual( fNeg, fValue )))
193 {
194 xErrorBarProp->setPropertyValue( "PositiveError" , uno::Any( fValue ));
195 xErrorBarProp->setPropertyValue( "NegativeError" , uno::Any( fValue ));
196 bChanged = true;
197 }
198 }
199 break;
200
202 {
203 double fValue =
204 static_cast< const SvxDoubleItem & >(
205 rItemSet.Get( nWhichId )).GetValue();
206 double fPos(0.0), fNeg(0.0);
207 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
208
209 if( ! ::rtl::math::approxEqual( fPos, fValue ))
210 {
211 GetPropertySet()->setPropertyValue( "PositiveError" , uno::Any( fValue ));
212 bChanged = true;
213 }
214 }
215 break;
216
218 {
220
221 double fValue =
222 static_cast< const SvxDoubleItem & >(
223 rItemSet.Get( nWhichId )).GetValue();
224 double fPos(0.0), fNeg(0.0);
225 lcl_getErrorValues( xErrorBarProp, fPos, fNeg );
226
227 if( ! ::rtl::math::approxEqual( fNeg, fValue ))
228 {
229 xErrorBarProp->setPropertyValue( "NegativeError" , uno::Any( fValue ));
230 bChanged = true;
231 }
232 }
233 break;
234
236 {
238
239 SvxChartIndicate eIndicate =
240 static_cast< const SvxChartIndicateItem & >(
241 rItemSet.Get( nWhichId )).GetValue();
242
243 bool bNewIndPos = (eIndicate == SvxChartIndicate::Both || eIndicate == SvxChartIndicate::Up );
244 bool bNewIndNeg = (eIndicate == SvxChartIndicate::Both || eIndicate == SvxChartIndicate::Down );
245
246 bool bShowPos(false), bShowNeg(false);
247 lcl_getErrorIndicatorValues( xErrorBarProp, bShowPos, bShowNeg );
248
249 if( bShowPos != bNewIndPos ||
250 bShowNeg != bNewIndNeg )
251 {
252 xErrorBarProp->setPropertyValue( "ShowPositiveError" , uno::Any( bNewIndPos ));
253 xErrorBarProp->setPropertyValue( "ShowNegativeError" , uno::Any( bNewIndNeg ));
254 bChanged = true;
255 }
256 }
257 break;
258
261 {
262 // @todo: also be able to deal with x-error bars
263 const bool bYError =
264 rItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue();
265
266 uno::Reference< chart2::data::XDataSource > xErrorBarSource( GetPropertySet(), uno::UNO_QUERY );
267 uno::Reference< chart2::XChartDocument > xChartDoc( m_xModel, uno::UNO_QUERY );
269
270 if( xChartDoc.is())
271 xDataProvider.set( xChartDoc->getDataProvider());
272 if( xErrorBarSource.is() && xDataProvider.is())
273 {
274 OUString aNewRange( static_cast< const SfxStringItem & >( rItemSet.Get( nWhichId )).GetValue());
275 bool bApplyNewRange = false;
276
277 bool bIsPositiveValue( nWhichId == SCHATTR_STAT_RANGE_POS );
278 if( xChartDoc->hasInternalDataProvider())
279 {
280 if( !aNewRange.isEmpty())
281 {
284 xErrorBarSource, bIsPositiveValue, bYError ));
285 if( ! xSeq.is())
286 {
287 // no data range for error bars yet => create
288 uno::Reference< chart2::XInternalDataProvider > xIntDataProvider( xDataProvider, uno::UNO_QUERY );
289 OSL_ASSERT( xIntDataProvider.is());
290 if( xIntDataProvider.is())
291 {
292 xIntDataProvider->appendSequence();
293 aNewRange = "last";
294 bApplyNewRange = true;
295 }
296 }
297 }
298 }
299 else
300 {
303 xErrorBarSource, bIsPositiveValue, bYError ));
304 bApplyNewRange =
305 ! ( xSeq.is() && (aNewRange == xSeq->getSourceRangeRepresentation()));
306 }
307
308 if( bApplyNewRange )
310 xErrorBarSource, xDataProvider, aNewRange, bIsPositiveValue, bYError );
311 }
312 }
313 break;
314 }
315
316 return bChanged;
317}
318
320 sal_uInt16 nWhichId, SfxItemSet & rOutItemSet ) const
321{
322 switch( nWhichId )
323 {
325 {
326 SvxChartKindError eErrorKind = SvxChartKindError::NONE;
328
329 sal_Int32 nStyle = 0;
330 if( xErrorBarProp->getPropertyValue( "ErrorBarStyle" ) >>= nStyle )
331 {
332 switch( nStyle )
333 {
334 case css::chart::ErrorBarStyle::NONE:
335 break;
336 case css::chart::ErrorBarStyle::VARIANCE:
337 eErrorKind = SvxChartKindError::Variant; break;
338 case css::chart::ErrorBarStyle::STANDARD_DEVIATION:
339 eErrorKind = SvxChartKindError::Sigma; break;
340 case css::chart::ErrorBarStyle::ABSOLUTE:
341 eErrorKind = SvxChartKindError::Const; break;
342 case css::chart::ErrorBarStyle::RELATIVE:
343 eErrorKind = SvxChartKindError::Percent; break;
344 case css::chart::ErrorBarStyle::ERROR_MARGIN:
345 eErrorKind = SvxChartKindError::BigError; break;
346 case css::chart::ErrorBarStyle::STANDARD_ERROR:
347 eErrorKind = SvxChartKindError::StdError; break;
348 case css::chart::ErrorBarStyle::FROM_DATA:
349 eErrorKind = SvxChartKindError::Range; break;
350 }
351 }
352 rOutItemSet.Put( SvxChartKindErrorItem( eErrorKind, SCHATTR_STAT_KIND_ERROR ));
353 }
354 break;
355
357 {
358 double fPos(0.0), fNeg(0.0);
359 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
360 rOutItemSet.Put( SvxDoubleItem( ( fPos + fNeg ) / 2.0, SCHATTR_STAT_PERCENT ));
361 }
362 break;
363
365 {
366 double fPos(0.0), fNeg(0.0);
367 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
368 rOutItemSet.Put( SvxDoubleItem( ( fPos + fNeg ) / 2.0, SCHATTR_STAT_BIGERROR ));
369 }
370 break;
371
373 {
374 double fPos(0.0), fNeg(0.0);
375 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
376 rOutItemSet.Put( SvxDoubleItem( fPos, SCHATTR_STAT_CONSTPLUS ));
377 }
378 break;
379
381 {
382 double fPos(0.0), fNeg(0.0);
383 lcl_getErrorValues( GetPropertySet(), fPos, fNeg );
384 rOutItemSet.Put( SvxDoubleItem( fNeg, SCHATTR_STAT_CONSTMINUS ));
385 }
386 break;
387
389 {
390 SvxChartIndicate eIndicate = SvxChartIndicate::Both;
391 bool bShowPos(false), bShowNeg(false);
392 lcl_getErrorIndicatorValues( GetPropertySet(), bShowPos, bShowNeg );
393
394 if( bShowPos )
395 {
396 if( bShowNeg )
397 eIndicate = SvxChartIndicate::Both;
398 else
399 eIndicate = SvxChartIndicate::Up;
400 }
401 else
402 {
403 if( bShowNeg )
404 eIndicate = SvxChartIndicate::Down;
405 else
406 eIndicate = SvxChartIndicate::NONE;
407 }
408 rOutItemSet.Put( SvxChartIndicateItem( eIndicate, SCHATTR_STAT_INDICATE ));
409 }
410 break;
411
414 {
415 const bool bYError =
416 rOutItemSet.Get(SCHATTR_STAT_ERRORBAR_TYPE).GetValue();
417
418 uno::Reference< chart2::data::XDataSource > xErrorBarSource( GetPropertySet(), uno::UNO_QUERY );
419 if( xErrorBarSource.is())
420 {
423 xErrorBarSource, (nWhichId == SCHATTR_STAT_RANGE_POS), bYError ));
424 if( xSeq.is())
425 rOutItemSet.Put( SfxStringItem( nWhichId, xSeq->getSourceRangeRepresentation()));
426 }
427 }
428 break;
429 }
430}
431
432} // namespace chart::wrapper
433
434/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr TypedWhichId< SfxStringItem > SCHATTR_STAT_RANGE_POS(SCHATTR_STAT_START+7)
constexpr TypedWhichId< SvxChartIndicateItem > SCHATTR_STAT_INDICATE(SCHATTR_STAT_START+6)
constexpr TypedWhichId< SfxBoolItem > SCHATTR_STAT_ERRORBAR_TYPE(SCHATTR_STAT_START+9)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_STAT_BIGERROR(SCHATTR_STAT_START+3)
constexpr TypedWhichId< SvxChartKindErrorItem > SCHATTR_STAT_KIND_ERROR(SCHATTR_STAT_START+1)
constexpr TypedWhichId< SfxStringItem > SCHATTR_STAT_RANGE_NEG(SCHATTR_STAT_START+8)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_STAT_CONSTPLUS(SCHATTR_STAT_START+4)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_STAT_CONSTMINUS(SCHATTR_STAT_START+5)
constexpr TypedWhichId< SvxDoubleItem > SCHATTR_STAT_PERCENT(SCHATTR_STAT_START+2)
const WhichRangesContainer nErrorBarWhichPairs(svl::Items< SCHATTR_STAT_START, SCHATTR_STAT_END, XATTR_LINE_FIRST, XATTR_LINE_LAST >)
SvxChartIndicate
SvxChartKindError
const OUString & GetValue() const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
ErrorBarItemConverter(css::uno::Reference< css::frame::XModel > xChartModel, const css::uno::Reference< css::beans::XPropertySet > &rPropertySet, SfxItemPool &rItemPool, SdrModel &rDrawModel, const css::uno::Reference< css::lang::XMultiServiceFactory > &xNamedPropertyContainerFactory)
css::uno::Reference< css::frame::XModel > m_xModel
virtual bool GetItemProperty(tWhichIdType nWhichId, tPropertyNameWithMemberId &rOutProperty) const override
implement this method to return a Property object for a given which id.
virtual bool ApplySpecialItem(sal_uInt16 nWhichId, const SfxItemSet &rItemSet) override
for items that can not be mapped directly to a property.
virtual void FillItemSet(SfxItemSet &rOutItemSet) const override
applies all properties that can be mapped to items into the given item set.
virtual bool ApplyItemSet(const SfxItemSet &rItemSet) override
applies all properties that are results of a conversion from all items in rItemSet to the internal XP...
virtual const WhichRangesContainer & GetWhichPairs() const override
implement this method to provide an array of which-ranges
std::shared_ptr< ItemConverter > m_spGraphicConverter
virtual void FillSpecialItem(sal_uInt16 nWhichId, SfxItemSet &rOutItemSet) const override
for items that can not be mapped directly to a property.
This class serves for conversion between properties of an XPropertySet and SfxItems in SfxItemSets.
virtual void FillItemSet(SfxItemSet &rOutItemSet) const
applies all properties that can be mapped to items into the given item set.
std::pair< tPropertyNameType, tMemberIdType > tPropertyNameWithMemberId
const css::uno::Reference< css::beans::XPropertySet > & GetPropertySet() const
Returns the XPropertySet that was given in the CTOR and is used to apply items in ApplyItemSet().
virtual bool ApplyItemSet(const SfxItemSet &rItemSet)
applies all properties that are results of a conversion from all items in rItemSet to the internal XP...
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< frame::XModel > m_xModel
OOO_DLLPUBLIC_CHARTTOOLS css::uno::Reference< css::chart2::data::XDataSequence > getErrorDataSequenceFromDataSource(const css::uno::Reference< css::chart2::data::XDataSource > &xDataSource, bool bPositiveValue, bool bYError=true)
OOO_DLLPUBLIC_CHARTTOOLS void setErrorDataSequence(const css::uno::Reference< css::chart2::data::XDataSource > &xDataSource, const css::uno::Reference< css::chart2::data::XDataProvider > &xDataProvider, const OUString &rNewRange, bool bPositiveValue, bool bYError=true, OUString const *pXMLRange=nullptr)
std::shared_ptr< T > make_shared(Args &&... args)
const char GetValue[]
Reference< XModel > xModel