1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <basegfx/numeric/ftools.hxx>
22 #include "VPolarAngleAxis.hxx"
23 #include "VPolarGrid.hxx"
24 #include "AbstractShapeFactory.hxx"
26 #include "NumberFormatterWrapper.hxx"
27 #include "PolarLabelPositionHelper.hxx"
28 #include <tools/color.hxx>
30 #include <boost/scoped_ptr.hpp>
34 using namespace ::com::sun::star
;
35 using namespace ::com::sun::star::chart2
;
36 using namespace ::rtl::math
;
38 VPolarAngleAxis::VPolarAngleAxis( const AxisProperties
& rAxisProperties
39 , const uno::Reference
< util::XNumberFormatsSupplier
>& xNumberFormatsSupplier
40 , sal_Int32 nDimensionCount
)
41 : VPolarAxis( rAxisProperties
, xNumberFormatsSupplier
, 0/*nDimensionIndex*/, nDimensionCount
)
45 VPolarAngleAxis::~VPolarAngleAxis()
51 bool VPolarAngleAxis::createTextShapes_ForAngleAxis(
52 const uno::Reference
< drawing::XShapes
>& xTarget
53 , EquidistantTickIter
& rTickIter
54 , AxisLabelProperties
& rAxisLabelProperties
58 sal_Int32 nDimensionCount
= 2;
59 AbstractShapeFactory
* pShapeFactory
= AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory
);
61 FixedNumberFormatter
aFixedNumberFormatter(
62 m_xNumberFormatsSupplier
, rAxisLabelProperties
.nNumberFormatKey
);
64 //prepare text properties for multipropertyset-interface of shape
65 tNameSequence aPropNames
;
66 tAnySequence aPropValues
;
68 uno::Reference
< beans::XPropertySet
> xProps( m_aAxisProperties
.m_xAxisModel
, uno::UNO_QUERY
);
69 PropertyMapper::getTextLabelMultiPropertyLists( xProps
, aPropNames
, aPropValues
, false );
70 LabelPositionHelper::doDynamicFontResize( aPropValues
, aPropNames
, xProps
71 , rAxisLabelProperties
.m_aFontReferenceSize
);
73 uno::Any
* pColorAny
= PropertyMapper::getValuePointer(aPropValues
,aPropNames
,"CharColor");
74 sal_Int32 nColor
= Color( COL_AUTO
).GetColor();
76 *pColorAny
>>= nColor
;
78 const uno::Sequence
< OUString
>* pLabels
= m_bUseTextLabels
? &m_aTextLabels
: 0;
80 //TickInfo* pLastVisibleNeighbourTickInfo = NULL;
83 for( TickInfo
* pTickInfo
= rTickIter
.firstInfo()
85 ; pTickInfo
= rTickIter
.nextInfo(), nTick
++ )
87 //don't create labels which does not fit into the rhythm
88 if( nTick
%rAxisLabelProperties
.nRhythm
!= 0)
91 //don't create labels for invisible ticks
92 if( !pTickInfo
->bPaintIt
)
95 //if NO OVERLAP -> don't create labels where the
96 //anchor position is the same as for the last label
99 if(!pTickInfo
->xTextShape
.is())
101 //create single label
102 bool bHasExtraColor
=false;
103 sal_Int32 nExtraColor
=0;
108 sal_Int32 nIndex
= static_cast< sal_Int32
>(pTickInfo
->getUnscaledTickValue()) - 1; //first category (index 0) matches with real number 1.0
109 if( nIndex
>=0 && nIndex
<pLabels
->getLength() )
110 aLabel
= (*pLabels
)[nIndex
];
113 aLabel
= aFixedNumberFormatter
.getFormattedString( pTickInfo
->getUnscaledTickValue(), nExtraColor
, bHasExtraColor
);
116 *pColorAny
= uno::makeAny(bHasExtraColor
?nExtraColor
:nColor
);
118 double fLogicAngle
= pTickInfo
->getUnscaledTickValue();
120 LabelAlignment
eLabelAlignment(LABEL_ALIGN_CENTER
);
121 PolarLabelPositionHelper
aPolarLabelPositionHelper(m_pPosHelper
,nDimensionCount
,xTarget
, pShapeFactory
);
122 sal_Int32 nScreenValueOffsetInRadiusDirection
= m_aAxisLabelProperties
.m_aMaximumSpaceForLabels
.Height
/15;
123 awt::Point
aAnchorScreenPosition2D( aPolarLabelPositionHelper
.getLabelScreenPositionAndAlignmentForLogicValues(
124 eLabelAlignment
, fLogicAngle
, fLogicRadius
, fLogicZ
, nScreenValueOffsetInRadiusDirection
));
125 LabelPositionHelper::changeTextAdjustment( aPropValues
, aPropNames
, eLabelAlignment
);
127 // #i78696# use mathematically correct rotation now
128 const double fRotationAnglePi(rAxisLabelProperties
.fRotationAngleDegree
* (F_PI
/ -180.0));
130 uno::Any aATransformation
= AbstractShapeFactory::makeTransformation( aAnchorScreenPosition2D
, fRotationAnglePi
);
131 OUString aStackedLabel
= AbstractShapeFactory::getStackedString( aLabel
, rAxisLabelProperties
.bStackCharacters
);
133 pTickInfo
->xTextShape
= pShapeFactory
->createText( xTarget
, aStackedLabel
, aPropNames
, aPropValues
, aATransformation
);
136 //if NO OVERLAP -> remove overlapping shapes
142 void VPolarAngleAxis::createMaximumLabels()
144 if( !prepareShapeCreation() )
150 void VPolarAngleAxis::updatePositions()
152 //todo: really only update the positions
154 if( !prepareShapeCreation() )
160 void VPolarAngleAxis::createLabels()
162 if( !prepareShapeCreation() )
165 double fLogicRadius
= m_pPosHelper
->getOuterLogicRadius();
167 if( m_aAxisProperties
.m_bDisplayLabels
)
169 //get the transformed screen values for all tickmarks in aAllTickInfos
170 boost::scoped_ptr
< TickFactory
> apTickFactory( this->createTickFactory() );
172 //create tick mark text shapes
173 //@todo: iterate through all tick depth which should be labeled
175 EquidistantTickIter
aTickIter( m_aAllTickInfos
, m_aIncrement
, 0, 0 );
176 this->updateUnscaledValuesAtTicks( aTickIter
);
178 removeTextShapesFromTicks();
180 AxisLabelProperties
aAxisLabelProperties( m_aAxisLabelProperties
);
181 aAxisLabelProperties
.bOverlapAllowed
= true;
182 double fLogicZ
= 1.0;//as defined
183 while( !createTextShapes_ForAngleAxis( m_xTextTarget
, aTickIter
184 , aAxisLabelProperties
185 , fLogicRadius
, fLogicZ
190 //no staggering for polar angle axis
194 void VPolarAngleAxis::createShapes()
196 if( !prepareShapeCreation() )
199 double fLogicRadius
= m_pPosHelper
->getOuterLogicRadius();
200 double fLogicZ
= 1.0;//as defined
202 //create axis main lines
203 drawing::PointSequenceSequence
aPoints(1);
204 VPolarGrid::createLinePointSequence_ForAngleAxis( aPoints
, m_aAllTickInfos
, m_aIncrement
, m_aScale
, m_pPosHelper
, fLogicRadius
, fLogicZ
);
205 uno::Reference
< drawing::XShape
> xShape
= m_pShapeFactory
->createLine2D(
206 m_xGroupShape_Shapes
, aPoints
, &m_aAxisProperties
.m_aLineProperties
);
207 //because of this name this line will be used for marking the axis
208 ::chart::AbstractShapeFactory::setShapeName( xShape
, "MarkHandles" );
216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */