1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: VDataSeries.cxx,v $
10 * $Revision: 1.32.8.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "VDataSeries.hxx"
34 #include "ObjectIdentifier.hxx"
36 #include "CommonConverters.hxx"
37 #include "LabelPositionHelper.hxx"
38 #include "ChartTypeHelper.hxx"
39 #include "ContainerHelper.hxx"
40 #include "DataSeriesHelper.hxx"
41 #include "RegressionCurveHelper.hxx"
43 #include <com/sun/star/chart/MissingValueTreatment.hpp>
44 #include <com/sun/star/chart2/Symbol.hpp>
46 //#include "CommonConverters.hxx"
47 #include <rtl/math.hxx>
48 #include <tools/debug.hxx>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/beans/XPropertyState.hpp>
51 #include <com/sun/star/drawing/LineStyle.hpp>
52 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
53 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
54 #include <com/sun/star/text/WritingMode.hpp>
55 #include <com/sun/star/chart2/data/XDataSource.hpp>
57 //.............................................................................
60 //.............................................................................
61 using namespace ::com::sun::star
;
62 using namespace ::com::sun::star::chart2
;
63 using ::com::sun::star::uno::Reference
;
65 void VDataSequence::init( const uno::Reference
< data::XDataSequence
>& xModel
)
68 Doubles
= DataSequenceToDoubleSequence( xModel
);
71 bool VDataSequence::is() const
75 void VDataSequence::clear()
81 double VDataSequence::getValue( sal_Int32 index
) const
83 if( 0<=index
&& index
<Doubles
.getLength() )
84 return Doubles
[index
];
88 ::rtl::math::setNan( & fNan
);
93 sal_Int32
VDataSequence::detectNumberFormatKey( sal_Int32 index
) const
95 sal_Int32 nNumberFormatKey
= -1;
97 // -1 is allowed and means a key for the whole sequence
98 if( -1<=index
&& index
<Doubles
.getLength() &&
101 nNumberFormatKey
= Model
->getNumberFormatKeyByIndex( index
);
104 return nNumberFormatKey
;
107 sal_Int32
VDataSequence::getLength() const
109 return Doubles
.getLength();
114 struct lcl_LessXOfPoint
116 inline bool operator() ( const std::vector
< double >& first
,
117 const std::vector
< double >& second
)
119 if( first
.size() > 0 && second
.size() > 0 )
121 return first
[0]<second
[0];
127 void lcl_clearIfNoValuesButTextIsContained( VDataSequence
& rData
, const uno::Reference
<data::XDataSequence
>& xDataSequence
)
129 //#i71686#, #i101968#, #i102428#
130 sal_Int32 nCount
= rData
.Doubles
.getLength();
131 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
133 if( !::rtl::math::isNan( rData
.Doubles
[i
] ) )
136 //no double value is countained
138 uno::Sequence
< rtl::OUString
> aStrings( DataSequenceToStringSequence( xDataSequence
) );
139 sal_Int32 nTextCount
= aStrings
.getLength();
140 for( sal_Int32 j
= 0; j
< nTextCount
; ++j
)
142 if( aStrings
[j
].getLength() )
151 void lcl_maybeReplaceNanWithZero( double& rfValue
, sal_Int32 nMissingValueTreatment
)
153 if( nMissingValueTreatment
== ::com::sun::star::chart::MissingValueTreatment::USE_ZERO
154 && (::rtl::math::isNan(rfValue
) || ::rtl::math::isInf(rfValue
)) )
160 VDataSeries::VDataSeries( const uno::Reference
< XDataSeries
>& xDataSeries
)
165 , m_xGroupShape(NULL
)
166 , m_xLabelsGroupShape(NULL
)
167 , m_xErrorBarsGroupShape(NULL
)
168 , m_xFrontSubGroupShape(NULL
)
169 , m_xBackSubGroupShape(NULL
)
170 , m_xDataSeries(xDataSeries
)
179 , m_aValues_Y_First()
181 , m_aValues_Bubble_Size()
182 , m_pValueSequenceForDataLabelNumberFormatDetection(&m_aValues_Y
)
186 , m_aAttributedDataPointIndexList()
188 , m_eStackingDirection(StackingDirection_NO_STACKING
)
190 , m_bConnectBars(sal_False
)
191 , m_bGroupBarsPerAxis(sal_True
)
192 , m_nStartingAngle(90)
194 , m_aSeriesParticle()
199 , m_nGlobalSeriesIndex(0)
201 , m_apLabel_Series(NULL
)
202 , m_apLabelPropNames_Series(NULL
)
203 , m_apLabelPropValues_Series(NULL
)
204 , m_apSymbolProperties_Series(NULL
)
206 , m_apLabel_AttributedPoint(NULL
)
207 , m_apLabelPropNames_AttributedPoint(NULL
)
208 , m_apLabelPropValues_AttributedPoint(NULL
)
209 , m_apSymbolProperties_AttributedPoint(NULL
)
210 , m_apSymbolProperties_InvisibleSymbolForSelection(NULL
)
211 , m_nCurrentAttributedPoint(-1)
212 , m_nMissingValueTreatment(::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP
)
213 , m_bAllowPercentValueInDataLabel(false)
215 ::rtl::math::setNan( & m_fYMeanValue
);
217 uno::Reference
<data::XDataSource
> xDataSource
=
218 uno::Reference
<data::XDataSource
>( xDataSeries
, uno::UNO_QUERY
);
220 m_aDataSequences
= xDataSource
->getDataSequences();
222 for(sal_Int32 nN
= m_aDataSequences
.getLength();nN
--;)
224 if(!m_aDataSequences
[nN
].is())
226 uno::Reference
<data::XDataSequence
> xDataSequence( m_aDataSequences
[nN
]->getValues());
227 uno::Reference
<beans::XPropertySet
> xProp(xDataSequence
, uno::UNO_QUERY
);
232 uno::Any aARole
= xProp
->getPropertyValue( C2U( "Role" ) );
236 if( aRole
.equals(C2U("values-x")) )
238 m_aValues_X
.init( xDataSequence
);
239 lcl_clearIfNoValuesButTextIsContained( m_aValues_X
, xDataSequence
);
241 else if( aRole
.equals(C2U("values-y")) )
242 m_aValues_Y
.init( xDataSequence
);
243 else if( aRole
.equals(C2U("values-min")) )
244 m_aValues_Y_Min
.init( xDataSequence
);
245 else if( aRole
.equals(C2U("values-max")) )
246 m_aValues_Y_Max
.init( xDataSequence
);
247 else if( aRole
.equals(C2U("values-first")) )
248 m_aValues_Y_First
.init( xDataSequence
);
249 else if( aRole
.equals(C2U("values-last")) )
250 m_aValues_Y_Last
.init( xDataSequence
);
251 else if( aRole
.equals(C2U("values-size")) )
252 m_aValues_Bubble_Size
.init( xDataSequence
);
254 catch( uno::Exception
& e
)
256 ASSERT_EXCEPTION( e
);
261 //determine the point count
262 m_nPointCount
= m_aValues_Y
.getLength();
264 if( m_nPointCount
< m_aValues_Bubble_Size
.getLength() )
265 m_nPointCount
= m_aValues_Bubble_Size
.getLength();
266 if( m_nPointCount
< m_aValues_Y_Min
.getLength() )
267 m_nPointCount
= m_aValues_Y_Min
.getLength();
268 if( m_nPointCount
< m_aValues_Y_Max
.getLength() )
269 m_nPointCount
= m_aValues_Y_Max
.getLength();
270 if( m_nPointCount
< m_aValues_Y_First
.getLength() )
271 m_nPointCount
= m_aValues_Y_First
.getLength();
272 if( m_nPointCount
< m_aValues_Y_Last
.getLength() )
273 m_nPointCount
= m_aValues_Y_Last
.getLength();
276 uno::Reference
<beans::XPropertySet
> xProp(xDataSeries
, uno::UNO_QUERY
);
281 //get AttributedDataPoints
282 xProp
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= m_aAttributedDataPointIndexList
;
284 xProp
->getPropertyValue( C2U( "StackingDirection" ) ) >>= m_eStackingDirection
;
286 xProp
->getPropertyValue( C2U( "AttachedAxisIndex" ) ) >>= m_nAxisIndex
;
290 catch( uno::Exception
& e
)
292 ASSERT_EXCEPTION( e
);
297 VDataSeries::~VDataSeries()
301 void VDataSeries::doSortByXValues()
303 if( m_aValues_X
.is() && m_aValues_X
.Doubles
.getLength() )
305 //prepare a vector vor sorting
306 std::vector
< ::std::vector
< double > > aTmp
;//outer vector are points, inner vector are the different values of athe point
308 ::rtl::math::setNan( & fNan
);
309 sal_Int32 nPointIndex
= 0;
310 for( nPointIndex
=0; nPointIndex
< m_nPointCount
; nPointIndex
++ )
312 std::vector
< double > aSinglePoint
;
313 aSinglePoint
.push_back( (nPointIndex
< m_aValues_X
.Doubles
.getLength()) ? m_aValues_X
.Doubles
[nPointIndex
] : fNan
);
314 aSinglePoint
.push_back( (nPointIndex
< m_aValues_Y
.Doubles
.getLength()) ? m_aValues_Y
.Doubles
[nPointIndex
] : fNan
);
315 aTmp
.push_back( aSinglePoint
);
319 std::sort( aTmp
.begin(), aTmp
.end(), lcl_LessXOfPoint() );
321 //fill the sorted points back to the mambers
322 m_aValues_X
.Doubles
.realloc( m_nPointCount
);
323 m_aValues_Y
.Doubles
.realloc( m_nPointCount
);
325 for( nPointIndex
=0; nPointIndex
< m_nPointCount
; nPointIndex
++ )
327 m_aValues_X
.Doubles
[nPointIndex
]=aTmp
[nPointIndex
][0];
328 m_aValues_Y
.Doubles
[nPointIndex
]=aTmp
[nPointIndex
][1];
333 uno::Reference
< XDataSeries
> VDataSeries::getModel() const
335 return m_xDataSeries
;
338 void VDataSeries::releaseShapes()
340 m_xGroupShape
.set(0);
341 m_xLabelsGroupShape
.set(0);
342 m_xErrorBarsGroupShape
.set(0);
343 m_xFrontSubGroupShape
.set(0);
344 m_xBackSubGroupShape
.set(0);
346 m_aPolyPolygonShape3D
.SequenceX
.realloc(0);
347 m_aPolyPolygonShape3D
.SequenceY
.realloc(0);
348 m_aPolyPolygonShape3D
.SequenceZ
.realloc(0);
352 void VDataSeries::setCategoryXAxis()
355 m_bAllowPercentValueInDataLabel
= true;
358 void VDataSeries::setGlobalSeriesIndex( sal_Int32 nGlobalSeriesIndex
)
360 m_nGlobalSeriesIndex
= nGlobalSeriesIndex
;
363 void VDataSeries::setParticle( const rtl::OUString
& rSeriesParticle
)
365 m_aSeriesParticle
= rSeriesParticle
;
368 m_aCID
= ObjectIdentifier::createClassifiedIdentifierForParticle( m_aSeriesParticle
);
369 m_aPointCID_Stub
= ObjectIdentifier::createSeriesSubObjectStub( OBJECTTYPE_DATA_POINT
, m_aSeriesParticle
);
371 m_aLabelCID_Stub
= ObjectIdentifier::createClassifiedIdentifierWithParent(
372 OBJECTTYPE_DATA_LABEL
, ::rtl::OUString(), getLabelsCID() );
374 rtl::OUString
VDataSeries::getSeriesParticle() const
376 return m_aSeriesParticle
;
378 rtl::OUString
VDataSeries::getCID() const
382 rtl::OUString
VDataSeries::getPointCID_Stub() const
384 return m_aPointCID_Stub
;
386 rtl::OUString
VDataSeries::getErrorBarsCID() const
388 rtl::OUString
aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_ERRORS
) );
389 aChildParticle
+=(C2U("="));
391 return ObjectIdentifier::createClassifiedIdentifierForParticles(
392 m_aSeriesParticle
, aChildParticle
);
394 rtl::OUString
VDataSeries::getLabelsCID() const
396 rtl::OUString
aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS
) );
397 aChildParticle
+=(C2U("="));
399 return ObjectIdentifier::createClassifiedIdentifierForParticles(
400 m_aSeriesParticle
, aChildParticle
);
402 rtl::OUString
VDataSeries::getLabelCID_Stub() const
404 return m_aLabelCID_Stub
;
406 rtl::OUString
VDataSeries::getDataCurveCID( sal_Int32 nCurveIndex
, bool bAverageLine
) const
409 aRet
= ObjectIdentifier::createDataCurveCID( m_aSeriesParticle
, nCurveIndex
, bAverageLine
);
413 rtl::OUString
VDataSeries::getDataCurveEquationCID( sal_Int32 nCurveIndex
) const
416 aRet
= ObjectIdentifier::createDataCurveEquationCID( m_aSeriesParticle
, nCurveIndex
);
419 void VDataSeries::setPageReferenceSize( const awt::Size
& rPageRefSize
)
421 m_aReferenceSize
= rPageRefSize
;
424 StackingDirection
VDataSeries::getStackingDirection() const
426 return m_eStackingDirection
;
428 sal_Int32
VDataSeries::getAttachedAxisIndex() const
432 void VDataSeries::setConnectBars( sal_Bool bConnectBars
)
434 m_bConnectBars
= bConnectBars
;
436 sal_Bool
VDataSeries::getConnectBars() const
438 return m_bConnectBars
;
440 void VDataSeries::setGroupBarsPerAxis( sal_Bool bGroupBarsPerAxis
)
442 m_bGroupBarsPerAxis
= bGroupBarsPerAxis
;
444 sal_Bool
VDataSeries::getGroupBarsPerAxis() const
446 return m_bGroupBarsPerAxis
;
449 void VDataSeries::setStartingAngle( sal_Int32 nStartingAngle
)
451 m_nStartingAngle
= nStartingAngle
;
453 sal_Int32
VDataSeries::getStartingAngle() const
455 return m_nStartingAngle
;
458 void VDataSeries::setAttachedAxisIndex( sal_Int32 nAttachedAxisIndex
)
460 if( nAttachedAxisIndex
< 0 )
461 nAttachedAxisIndex
= 0;
462 m_nAxisIndex
= nAttachedAxisIndex
;
465 sal_Int32
VDataSeries::getTotalPointCount() const
467 return m_nPointCount
;
470 double VDataSeries::getXValue( sal_Int32 index
) const
475 if( 0<=index
&& index
<m_aValues_X
.getLength() )
476 fRet
= m_aValues_X
.Doubles
[index
];
478 ::rtl::math::setNan( &fRet
);
482 // #i70133# always return correct X position - needed for short data series
483 if( 0<=index
/*&& index < m_nPointCount*/ )
484 fRet
= index
+1;//first category (index 0) matches with real number 1.0
486 ::rtl::math::setNan( &fRet
);
488 lcl_maybeReplaceNanWithZero( fRet
, getMissingValueTreatment() );
492 double VDataSeries::getYValue( sal_Int32 index
) const
497 if( 0<=index
&& index
<m_aValues_Y
.getLength() )
498 fRet
= m_aValues_Y
.Doubles
[index
];
500 ::rtl::math::setNan( &fRet
);
504 // #i70133# always return correct X position - needed for short data series
505 if( 0<=index
/*&& index < m_nPointCount*/ )
506 fRet
= index
+1;//first category (index 0) matches with real number 1.0
508 ::rtl::math::setNan( &fRet
);
510 lcl_maybeReplaceNanWithZero( fRet
, getMissingValueTreatment() );
514 double VDataSeries::getY_Min( sal_Int32 index
) const
516 return m_aValues_Y_Min
.getValue( index
);
518 double VDataSeries::getY_Max( sal_Int32 index
) const
520 return m_aValues_Y_Max
.getValue( index
);
522 double VDataSeries::getY_First( sal_Int32 index
) const
524 return m_aValues_Y_First
.getValue( index
);
526 double VDataSeries::getY_Last( sal_Int32 index
) const
528 return m_aValues_Y_Last
.getValue( index
);
530 double VDataSeries::getBubble_Size( sal_Int32 index
) const
532 return m_aValues_Bubble_Size
.getValue( index
);
535 bool VDataSeries::hasExplicitNumberFormat( sal_Int32 nPointIndex
, bool bForPercentage
) const
537 rtl::OUString
aPropName( bForPercentage
? C2U( "PercentageNumberFormat" ) : C2U( "NumberFormat" ) );
538 bool bHasNumberFormat
= false;
539 uno::Reference
< beans::XPropertySet
> xPointProp( this->getPropertiesOfPoint( nPointIndex
));
540 sal_Int32 nNumberFormat
= -1;
541 if( xPointProp
.is() && (xPointProp
->getPropertyValue(aPropName
) >>= nNumberFormat
) )
542 bHasNumberFormat
= true;
543 return bHasNumberFormat
;
545 sal_Int32
VDataSeries::getExplicitNumberFormat( sal_Int32 nPointIndex
, bool bForPercentage
) const
547 rtl::OUString
aPropName( bForPercentage
? C2U( "PercentageNumberFormat" ) : C2U( "NumberFormat" ) );
548 sal_Int32 nNumberFormat
= -1;
549 uno::Reference
< beans::XPropertySet
> xPointProp( this->getPropertiesOfPoint( nPointIndex
));
550 if( xPointProp
.is() )
551 xPointProp
->getPropertyValue(aPropName
) >>= nNumberFormat
;
552 return nNumberFormat
;
554 void VDataSeries::setRoleOfSequenceForDataLabelNumberFormatDetection( const rtl::OUString
& rRole
)
556 if( rRole
.equals(C2U("values-y")) )
557 m_pValueSequenceForDataLabelNumberFormatDetection
= &m_aValues_Y
;
558 else if( rRole
.equals(C2U("values-size")) )
559 m_pValueSequenceForDataLabelNumberFormatDetection
= &m_aValues_Bubble_Size
;
560 else if( rRole
.equals(C2U("values-min")) )
561 m_pValueSequenceForDataLabelNumberFormatDetection
= &m_aValues_Y_Min
;
562 else if( rRole
.equals(C2U("values-max")) )
563 m_pValueSequenceForDataLabelNumberFormatDetection
= &m_aValues_Y_Max
;
564 else if( rRole
.equals(C2U("values-first")) )
565 m_pValueSequenceForDataLabelNumberFormatDetection
= &m_aValues_Y_First
;
566 else if( rRole
.equals(C2U("values-last")) )
567 m_pValueSequenceForDataLabelNumberFormatDetection
= &m_aValues_Y_Last
;
568 else if( rRole
.equals(C2U("values-x")) )
569 m_pValueSequenceForDataLabelNumberFormatDetection
= &m_aValues_X
;
571 bool VDataSeries::shouldLabelNumberFormatKeyBeDetectedFromYAxis() const
573 if( m_pValueSequenceForDataLabelNumberFormatDetection
== &m_aValues_Bubble_Size
)
575 else if( m_pValueSequenceForDataLabelNumberFormatDetection
== &m_aValues_X
)
579 sal_Int32
VDataSeries::detectNumberFormatKey( sal_Int32 index
) const
582 if( m_pValueSequenceForDataLabelNumberFormatDetection
)
583 nRet
= m_pValueSequenceForDataLabelNumberFormatDetection
->detectNumberFormatKey( index
);
587 sal_Int32
VDataSeries::getLabelPlacement( sal_Int32 nPointIndex
, const uno::Reference
< chart2::XChartType
>& xChartType
, sal_Int32 nDimensionCount
, sal_Bool bSwapXAndY
) const
589 sal_Int32 nLabelPlacement
=0;
592 uno::Reference
< beans::XPropertySet
> xPointProps( this->getPropertiesOfPoint( nPointIndex
) );
593 if( xPointProps
.is() )
594 xPointProps
->getPropertyValue( C2U( "LabelPlacement" ) ) >>= nLabelPlacement
;
596 //ensure that the set label placement is supported by this charttype
598 uno::Sequence
< sal_Int32
> aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
599 xChartType
, nDimensionCount
, bSwapXAndY
, m_xDataSeries
) );
601 for( sal_Int32 nN
= 0; nN
< aAvailablePlacements
.getLength(); nN
++ )
602 if( aAvailablePlacements
[nN
] == nLabelPlacement
)
603 return nLabelPlacement
; //ok
605 //otherwise use the first supported one
606 if( aAvailablePlacements
.getLength() )
608 nLabelPlacement
= aAvailablePlacements
[0];
609 return nLabelPlacement
;
612 DBG_ERROR("no label placement supported");
614 catch( uno::Exception
& e
)
616 ASSERT_EXCEPTION( e
);
618 return nLabelPlacement
;
621 double VDataSeries::getMinimumofAllDifferentYValues( sal_Int32 index
) const
623 double fY
= getYValue( index
);
624 double fY_Min
= getY_Min( index
);
625 double fY_Max
= getY_Max( index
);
626 double fY_First
= getY_First( index
);
627 double fY_Last
= getY_Last( index
);
630 ::rtl::math::setInf(&fMin
, false);
642 if( ::rtl::math::isInf(fMin
) )
643 ::rtl::math::setNan(&fMin
);
648 double VDataSeries::getMaximumofAllDifferentYValues( sal_Int32 index
) const
650 double fY
= getYValue( index
);
651 double fY_Min
= getY_Min( index
);
652 double fY_Max
= getY_Max( index
);
653 double fY_First
= getY_First( index
);
654 double fY_Last
= getY_Last( index
);
657 ::rtl::math::setInf(&fMax
, true);
669 if( ::rtl::math::isInf(fMax
) )
670 ::rtl::math::setNan(&fMax
);
675 uno::Sequence
< double > VDataSeries::getAllX() const
677 if(!m_aValues_X
.is() && !m_aValues_X
.getLength() && m_nPointCount
)
679 //init x values from category indexes
680 //first category (index 0) matches with real number 1.0
681 m_aValues_X
.Doubles
.realloc( m_nPointCount
);
682 for(sal_Int32 nN
=m_aValues_X
.getLength();nN
--;)
683 m_aValues_X
.Doubles
[nN
] = nN
+1;
685 return m_aValues_X
.Doubles
;
688 uno::Sequence
< double > VDataSeries::getAllY() const
690 if(!m_aValues_Y
.is() && !m_aValues_Y
.getLength() && m_nPointCount
)
692 //init y values from indexes
693 //first y-value (index 0) matches with real number 1.0
694 m_aValues_Y
.Doubles
.realloc( m_nPointCount
);
695 for(sal_Int32 nN
=m_aValues_Y
.getLength();nN
--;)
696 m_aValues_Y
.Doubles
[nN
] = nN
+1;
698 return m_aValues_Y
.Doubles
;
701 double VDataSeries::getYMeanValue() const
703 if( ::rtl::math::isNan( m_fYMeanValue
) )
705 uno::Reference
< XRegressionCurveCalculator
> xCalculator( RegressionCurveHelper::createRegressionCurveCalculatorByServiceName( C2U("com.sun.star.chart2.MeanValueRegressionCurve") ) );
706 uno::Sequence
< double > aXValuesDummy
;
707 xCalculator
->recalculateRegression( aXValuesDummy
, getAllY() );
708 double fXDummy
= 1.0;
709 m_fYMeanValue
= xCalculator
->getCurveValue( fXDummy
);
711 return m_fYMeanValue
;
714 ::std::auto_ptr
< Symbol
> getSymbolPropertiesFromPropertySet(
715 const uno::Reference
< beans::XPropertySet
>& xProp
)
717 ::std::auto_ptr
< Symbol
> apSymbolProps( new Symbol() );
720 if( xProp
->getPropertyValue( C2U( "Symbol" ) ) >>= *apSymbolProps
)
722 // border of symbols always black
723 apSymbolProps
->BorderColor
= 0x000000;
724 //use main color to fill symbols
725 xProp
->getPropertyValue( C2U( "Color" ) ) >>= apSymbolProps
->FillColor
;
728 apSymbolProps
.reset();
730 catch( uno::Exception
&e
)
732 ASSERT_EXCEPTION( e
);
734 return apSymbolProps
;
737 Symbol
* VDataSeries::getSymbolProperties( sal_Int32 index
) const
740 if( isAttributedDataPoint( index
) )
742 adaptPointCache( index
);
743 if(!m_apSymbolProperties_AttributedPoint
.get())
744 m_apSymbolProperties_AttributedPoint
= getSymbolPropertiesFromPropertySet( this->getPropertiesOfPoint( index
) );
745 pRet
= m_apSymbolProperties_AttributedPoint
.get();
746 //if a single data point does not have symbols but the dataseries itself has symbols
747 //we create an invisible symbol shape to enable selection of that point
748 if( !pRet
|| pRet
->Style
== SymbolStyle_NONE
)
750 if(!m_apSymbolProperties_Series
.get())
751 m_apSymbolProperties_Series
= getSymbolPropertiesFromPropertySet( this->getPropertiesOfSeries() );
752 if( m_apSymbolProperties_Series
.get() && m_apSymbolProperties_Series
->Style
!= SymbolStyle_NONE
)
754 if(!m_apSymbolProperties_InvisibleSymbolForSelection
.get())
756 m_apSymbolProperties_InvisibleSymbolForSelection
= ::std::auto_ptr
< Symbol
>( new Symbol() );
757 m_apSymbolProperties_InvisibleSymbolForSelection
->Style
= SymbolStyle_STANDARD
;
758 m_apSymbolProperties_InvisibleSymbolForSelection
->StandardSymbol
= 0;//square
759 m_apSymbolProperties_InvisibleSymbolForSelection
->Size
= m_apSymbolProperties_Series
->Size
;
760 m_apSymbolProperties_InvisibleSymbolForSelection
->BorderColor
= 0xff000000;//invisible
761 m_apSymbolProperties_InvisibleSymbolForSelection
->FillColor
= 0xff000000;//invisible
763 pRet
= m_apSymbolProperties_InvisibleSymbolForSelection
.get();
769 if(!m_apSymbolProperties_Series
.get())
770 m_apSymbolProperties_Series
= getSymbolPropertiesFromPropertySet( this->getPropertiesOfSeries() );
771 pRet
= m_apSymbolProperties_Series
.get();
774 if( pRet
&& pRet
->Style
== SymbolStyle_AUTO
)
776 pRet
->Style
= SymbolStyle_STANDARD
;
778 sal_Int32 nIndex
= m_nGlobalSeriesIndex
;
781 pRet
->StandardSymbol
= nIndex
;
787 uno::Reference
< beans::XPropertySet
> VDataSeries::getYErrorBarProperties( sal_Int32 index
) const
789 uno::Reference
< beans::XPropertySet
> xErrorBarProp
;
791 uno::Reference
< beans::XPropertySet
> xPointProp( this->getPropertiesOfPoint( index
));
792 if( xPointProp
.is() )
793 xPointProp
->getPropertyValue( C2U( "ErrorBarY" )) >>= xErrorBarProp
;
794 return xErrorBarProp
;
797 bool VDataSeries::hasPointOwnColor( sal_Int32 index
) const
799 if( !isAttributedDataPoint(index
) )
804 uno::Reference
< beans::XPropertyState
> xPointState( this->getPropertiesOfPoint(index
), uno::UNO_QUERY_THROW
);
805 return (xPointState
->getPropertyState( C2U("Color")) != beans::PropertyState_DEFAULT_VALUE
);
807 catch( uno::Exception
& e
)
809 ASSERT_EXCEPTION( e
);
814 bool VDataSeries::isAttributedDataPoint( sal_Int32 index
) const
816 //returns true if the data point assigned by the given index has set it's own properties
817 if( index
>=m_nPointCount
|| m_nPointCount
==0)
819 for(sal_Int32 nN
=m_aAttributedDataPointIndexList
.getLength();nN
--;)
821 if(index
==m_aAttributedDataPointIndexList
[nN
])
827 bool VDataSeries::isVaryColorsByPoint() const
829 bool bVaryColorsByPoint
= false;
830 Reference
< beans::XPropertySet
> xSeriesProp( this->getPropertiesOfSeries() );
831 if( xSeriesProp
.is() )
832 xSeriesProp
->getPropertyValue( C2U("VaryColorsByPoint") ) >>= bVaryColorsByPoint
;
833 return bVaryColorsByPoint
;
836 uno::Reference
< beans::XPropertySet
> VDataSeries::getPropertiesOfPoint( sal_Int32 index
) const
838 if( isAttributedDataPoint( index
) )
839 return m_xDataSeries
->getDataPointByIndex(index
);
840 return this->getPropertiesOfSeries();
843 uno::Reference
< beans::XPropertySet
> VDataSeries::getPropertiesOfSeries() const
845 return uno::Reference
<beans::XPropertySet
>(m_xDataSeries
, uno::UNO_QUERY
);
848 ::std::auto_ptr
< DataPointLabel
> getDataPointLabelFromPropertySet(
849 const uno::Reference
< beans::XPropertySet
>& xProp
)
851 ::std::auto_ptr
< DataPointLabel
> apLabel( new DataPointLabel() );
854 if( !(xProp
->getPropertyValue( C2U( "Label" ) ) >>= *apLabel
) )
857 catch( uno::Exception
&e
)
859 ASSERT_EXCEPTION( e
);
864 void VDataSeries::adaptPointCache( sal_Int32 nNewPointIndex
) const
866 if( m_nCurrentAttributedPoint
!= nNewPointIndex
)
868 m_apLabel_AttributedPoint
.reset();
869 m_apLabelPropNames_AttributedPoint
.reset();
870 m_apLabelPropValues_AttributedPoint
.reset();
871 m_apSymbolProperties_AttributedPoint
.reset();
872 m_nCurrentAttributedPoint
= nNewPointIndex
;
876 DataPointLabel
* VDataSeries::getDataPointLabel( sal_Int32 index
) const
878 DataPointLabel
* pRet
= NULL
;
879 if( isAttributedDataPoint( index
) )
881 adaptPointCache( index
);
882 if( !m_apLabel_AttributedPoint
.get() )
883 m_apLabel_AttributedPoint
= getDataPointLabelFromPropertySet( this->getPropertiesOfPoint( index
) );
884 pRet
= m_apLabel_AttributedPoint
.get();
888 if(!m_apLabel_Series
.get())
889 m_apLabel_Series
= getDataPointLabelFromPropertySet( this->getPropertiesOfPoint( index
) );
890 pRet
= m_apLabel_Series
.get();
892 if( !m_bAllowPercentValueInDataLabel
)
895 pRet
->ShowNumberInPercent
= false;
900 DataPointLabel
* VDataSeries::getDataPointLabelIfLabel( sal_Int32 index
) const
902 DataPointLabel
* pLabel
= this->getDataPointLabel( index
);
903 if( !pLabel
|| (!pLabel
->ShowNumber
&& !pLabel
->ShowNumberInPercent
904 && !pLabel
->ShowCategoryName
) )
909 bool VDataSeries::getTextLabelMultiPropertyLists( sal_Int32 index
910 , tNameSequence
*& pPropNames
911 , tAnySequence
*& pPropValues
) const
913 pPropNames
= NULL
; pPropValues
= NULL
;
914 uno::Reference
< beans::XPropertySet
> xTextProp
;
915 bool bDoDynamicFontResize
= false;
916 if( isAttributedDataPoint( index
) )
918 adaptPointCache( index
);
919 if(!m_apLabelPropValues_AttributedPoint
.get())
921 pPropNames
= new tNameSequence();
922 pPropValues
= new tAnySequence();
923 xTextProp
.set( this->getPropertiesOfPoint( index
));
924 PropertyMapper::getTextLabelMultiPropertyLists( xTextProp
, *pPropNames
, *pPropValues
);
925 m_apLabelPropNames_AttributedPoint
= ::std::auto_ptr
< tNameSequence
>(pPropNames
);
926 m_apLabelPropValues_AttributedPoint
= ::std::auto_ptr
< tAnySequence
>(pPropValues
);
927 bDoDynamicFontResize
= true;
929 pPropNames
= m_apLabelPropNames_AttributedPoint
.get();
930 pPropValues
= m_apLabelPropValues_AttributedPoint
.get();
934 if(!m_apLabelPropValues_Series
.get())
936 pPropNames
= new tNameSequence();
937 pPropValues
= new tAnySequence();
938 xTextProp
.set( this->getPropertiesOfPoint( index
));
939 PropertyMapper::getTextLabelMultiPropertyLists( xTextProp
, *pPropNames
, *pPropValues
);
940 m_apLabelPropNames_Series
= ::std::auto_ptr
< tNameSequence
>(pPropNames
);
941 m_apLabelPropValues_Series
= ::std::auto_ptr
< tAnySequence
>(pPropValues
);
942 bDoDynamicFontResize
= true;
944 pPropNames
= m_apLabelPropNames_Series
.get();
945 pPropValues
= m_apLabelPropValues_Series
.get();
948 if( bDoDynamicFontResize
&&
949 pPropNames
&& pPropValues
&&
952 LabelPositionHelper::doDynamicFontResize( *pPropValues
, *pPropNames
, xTextProp
, m_aReferenceSize
);
954 if(pPropNames
&&pPropValues
)
959 void VDataSeries::setMissingValueTreatment( sal_Int32 nMissingValueTreatment
)
961 m_nMissingValueTreatment
= nMissingValueTreatment
;
964 sal_Int32
VDataSeries::getMissingValueTreatment() const
966 return m_nMissingValueTreatment
;
969 //.............................................................................
971 //.............................................................................