31#include <com/sun/star/chart2/AxisType.hpp>
33#include <rtl/math.hxx>
56using ::com::sun::star::uno::Reference;
57using ::basegfx::B2DVector;
58using ::basegfx::B2DPolygon;
59using ::basegfx::B2DPolyPolygon;
65 , sal_Int32 nDimensionIndex, sal_Int32 nDimensionCount
67 :
VAxisBase( nDimensionIndex, nDimensionCount, rAxisProperties, xNumberFormatsSupplier )
83 std::u16string_view rLabel,
86 const bool bIsHorizontalAxis )
89 bool bIsDirectionVertical = bIsHorizontalAxis && bTextHorizontal;
92 if( !nFullSize || rLabel.empty() )
95 const sal_Int32 nAvgCharWidth = rShape2DText.
getSize().Width / rLabel.size();
101 const sal_Int32 nTextSize = bIsDirectionVertical ? aSizeAfterRotation.Height : aSizeAfterRotation.Width;
106 static constexpr OUStringLiteral sDots =
u"...";
107 const sal_Int32 nCharsToRemove = ( nTextSize - nMaxLabelsSize ) / nAvgCharWidth + 1;
108 sal_Int32 nNewLen = rLabel.size() - nCharsToRemove - sDots.getLength();
111 nNewLen = ( sal_Int32(rLabel.size()) >= sDots.getLength() ) ? sDots.getLength() : rLabel.size();
113 bool bCrop = nCharsToRemove > 0;
117 OUString aNewLabel( rLabel.substr( 0, nNewLen ) );
118 if( nNewLen > sDots.getLength() )
127 ,
const awt::Point& rAnchorScreenPosition2D
128 ,
const OUString& rLabel
133 ,
const bool bIsHorizontalAxis
157 ,
double fRotationAngleDegree
163 static_cast<sal_Int32
>( rTickScreenPosition.
getX() )
164 ,
static_cast<sal_Int32
>( rTickScreenPosition.
getY() ) );
165 return aShapeRect.
isInside(aPosition);
168static void lcl_getRotatedPolygon( B2DPolygon &aPoly, const ::basegfx::B2DRectangle &aRect,
const awt::Point &aPos,
const double fRotationAngleDegree )
185 aPoly.transform( aMatrix );
190 ,
double fRotationAngleDegree )
192 if( !xShape1.is() || !xShape2.is() )
203 B2DPolyPolygon aPolyPoly1, aPolyPoly2;
204 aPolyPoly1.append( aPoly1 );
205 aPolyPoly2.append( aPoly2 );
206 B2DPolyPolygon overlapPoly = ::basegfx::utils::clipPolyPolygonOnPolyPolygon( aPolyPoly1, aPolyPoly2,
true,
false );
208 return (overlapPoly.count() > 0);
212 , sal_Int32 nCorrectRhythm
213 , sal_Int32 nMaxTickToCheck
218 ; pTickInfo && nTick <= nMaxTickToCheck
219 ; pTickInfo = rIter.
nextInfo(), nTick++ )
222 if( nTick%nCorrectRhythm != 0)
224 if(pTickInfo->xTextShape.is())
226 xTarget->remove(pTickInfo->xTextShape);
227 pTickInfo->xTextShape =
nullptr;
244class LabelIterator :
public TickIter
251 virtual TickInfo* firstInfo()
override;
252 virtual TickInfo* nextInfo()
override;
271TickInfo* LabelIterator::firstInfo()
274 while( pTickInfo && !pTickInfo->xTextShape.is() )
286 while( pTickInfo && !pTickInfo->xTextShape.is() );
293TickInfo* LabelIterator::nextInfo()
295 TickInfo* pTickInfo =
nullptr;
299 while( pTickInfo && !pTickInfo->xTextShape.is() );
307 while( pTickInfo && !pTickInfo->xTextShape.is() );
319 sal_Int32 nDistanceTickToText =
static_cast<sal_Int32
>( rDistanceTickToText.getLength() );
320 if( nDistanceTickToText==0.0)
323 B2DVector aStaggerDirection(rDistanceTickToText);
324 aStaggerDirection.normalize();
326 sal_Int32 nDistance=0;
332 xShape2DText = pTickInfo->xTextShape;
333 if( xShape2DText.is() )
335 awt::Size aSize = ShapeFactory::getSizeAfterRotation( *xShape2DText, fRotationAngleDegree );
336 if(fabs(aStaggerDirection.getX())>fabs(aStaggerDirection.getY()))
337 nDistance = std::max(nDistance,aSize.Width);
339 nDistance = std::max(nDistance,aSize.Height);
343 aRet = aStaggerDirection*nDistance;
346 if(fabs(aStaggerDirection.getX())>fabs(aStaggerDirection.getY()))
347 aRet += rDistanceTickToText;
354 if(rStaggerDistance.getLength()==0.0)
361 if( xShape2DText.is() )
363 awt::Point aPos = xShape2DText->getPosition();
364 aPos.X +=
static_cast<sal_Int32
>(rStaggerDistance.getX());
365 aPos.Y +=
static_cast<sal_Int32
>(rStaggerDistance.getY());
366 xShape2DText->setPosition( aPos );
377 if (!pTextEditSource)
386 for ( sal_Int32 nPara = 0; nPara < nParaCount; ++nPara )
388 sal_Int32 nLineCount = pTextForwarder->
GetLineCount( nPara );
389 for ( sal_Int32 nLine = 0; nLine < nLineCount; ++nLine )
391 sal_Int32 nLineStart = 0;
392 sal_Int32 nLineEnd = 0;
394 assert(nLineStart >= 0);
395 sal_Int32 nWordStart = 0;
396 sal_Int32 nWordEnd = 0;
397 if ( pTextForwarder->
GetWordIndices( nPara, nLineStart, nWordStart, nWordEnd ) &&
398 ( nWordStart != nLineStart ) )
410 const TickInfo* pTickInfo,
bool bComplexCat,
Color& rExtraColor,
bool& rHasExtraColor )
418 return (*pCategories)[
nIndex];
422 else if (bComplexCat)
425 return pTickInfo->
aText;
435 sal_Int32 nLimitedSpaceForText,
bool bLimitedHeight )
439 PropertyMapper::getTextLabelMultiPropertyLists(
440 xProps, rPropNames, rPropValues,
false, nLimitedSpaceForText, bLimitedHeight,
false);
442 LabelPositionHelper::doDynamicFontResize(
445 LabelPositionHelper::changeTextAdjustment(
457class MaxLabelTickIter :
public TickIter
460 MaxLabelTickIter(
TickInfoArrayType& rTickInfoVector,
size_t nLongestLabelIndex );
462 virtual TickInfo* firstInfo()
override;
463 virtual TickInfo* nextInfo()
override;
473MaxLabelTickIter::MaxLabelTickIter(
477 assert(!rTickInfoVector.empty());
478 assert(nLongestLabelIndex < rTickInfoVector.size());
481 if (nLongestLabelIndex >= nMaxIndex-1)
482 nLongestLabelIndex = 0;
484 if (nLongestLabelIndex > 0)
491 ++nLongestLabelIndex;
492 if (nLongestLabelIndex > nMaxIndex)
499TickInfo* MaxLabelTickIter::firstInfo()
507TickInfo* MaxLabelTickIter::nextInfo()
515bool VCartesianAxis::isBreakOfLabelsAllowed(
516 const AxisLabelProperties& rAxisLabelProperties,
bool bIsHorizontalAxis,
bool bIsVerticalAxis)
const
518 if( m_aTextLabels.getLength() > 100 )
525 if( !m_bUseTextLabels )
532 if( !m_aAxisProperties.m_bSwapXAndY )
533 return bIsHorizontalAxis;
534 else if( m_aAxisProperties.m_bSwapXAndY && !m_aAxisProperties.m_bComplexCategories )
535 return bIsVerticalAxis;
541bool canAutoAdjustLabelPlacement(
542 const AxisLabelProperties& rAxisLabelProperties,
bool bIsHorizontalAxis,
bool bIsVerticalAxis)
554 if( bIsHorizontalAxis )
556 if( bIsVerticalAxis )
561bool isAutoStaggeringOfLabelsAllowed(
562 const AxisLabelProperties& rAxisLabelProperties,
bool bIsHorizontalAxis,
bool bIsVerticalAxis )
564 if( rAxisLabelProperties.m_eStaggering != AxisLabelStaggering::StaggerAuto )
566 return canAutoAdjustLabelPlacement(rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis);
570const auto& isAutoRotatingOfLabelsAllowed = canAutoAdjustLabelPlacement;
573void VCartesianAxis::createAllTickInfosFromComplexCategories(
TickInfoArraysType& rAllTickInfos,
bool bShiftedPosition )
577 if(!bShiftedPosition)
579 rAllTickInfos.clear();
581 sal_Int32 nLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
582 for( ; nLevel<nLevelCount; nLevel++ )
585 const std::vector<ComplexCategory>* pComplexCategories =
586 m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoriesByLevel(nLevel);
588 if (!pComplexCategories)
591 sal_Int32 nCatIndex = 0;
593 for (
auto const& complexCategory : *pComplexCategories)
596 sal_Int32
nCount = complexCategory.Count;
597 if( nCatIndex + 1.0 +
nCount >= m_aScale.Maximum )
599 nCount =
static_cast<sal_Int32
>(m_aScale.Maximum - 1.0 - nCatIndex);
605 aTickInfo.
aText = complexCategory.Text;
606 aTickInfoVector.push_back(aTickInfo);
608 if( nCatIndex + 1.0 >= m_aScale.Maximum )
611 rAllTickInfos.push_back(aTickInfoVector);
616 rAllTickInfos.clear();
618 sal_Int32 nLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
619 for( ; nLevel<nLevelCount; nLevel++ )
622 const std::vector<ComplexCategory>* pComplexCategories =
623 m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoriesByLevel(nLevel);
624 sal_Int32 nCatIndex = 0;
625 if (pComplexCategories)
627 for (
auto const& complexCategory : *pComplexCategories)
631 aTickInfoVector.push_back(aTickInfo);
632 nCatIndex += complexCategory.Count;
633 if( nCatIndex + 1.0 > m_aScale.Maximum )
639 while( nCatIndex + 1.0 < m_aScale.Maximum )
643 aTickInfoVector.push_back(aTickInfo);
652 aTickInfoVector.push_back(aTickInfo);
654 rAllTickInfos.push_back(aTickInfoVector);
661 if( isComplexCategoryAxis() )
662 createAllTickInfosFromComplexCategories( rAllTickInfos,
false );
664 VAxisBase::createAllTickInfos(rAllTickInfos);
667TickIter* VCartesianAxis::createLabelTickIterator( sal_Int32 nTextLevel )
674TickIter* VCartesianAxis::createMaximumLabelTickIterator( sal_Int32 nTextLevel )
676 if( isComplexCategoryAxis() || isDateAxis() )
678 return createLabelTickIterator( nTextLevel );
684 if( !m_aAllTickInfos.empty() )
686 size_t nLongestLabelIndex = m_bUseTextLabels ? getIndexOfLongestLabel(m_aTextLabels) : 0;
687 if (nLongestLabelIndex >= m_aAllTickInfos[0].
size())
690 return new MaxLabelTickIter( m_aAllTickInfos[0], nLongestLabelIndex );
697sal_Int32 VCartesianAxis::getTextLevelCount()
const
699 sal_Int32 nTextLevelCount = 1;
700 if( isComplexCategoryAxis() )
701 nTextLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
702 return nTextLevelCount;
705bool VCartesianAxis::createTextShapes(
708 sal_Int32 nScreenDistanceBetweenTicks )
713 if( m_bUseTextLabels && (m_aAxisProperties.m_eLabelPos == css::chart::ChartAxisLabelPosition_NEAR_AXIS ||
714 m_aAxisProperties.m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_START))
716 if (bIsHorizontalAxis)
721 else if (bIsVerticalAxis)
728 bool bIsBreakOfLabelsAllowed = isBreakOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis );
729 if (!bIsBreakOfLabelsAllowed &&
730 !isAutoStaggeringOfLabelsAllowed(rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis) &&
733 return createTextShapesSimple(
xTarget, rTickIter, rAxisLabelProperties, pTickFactory);
739 bool bIsStaggered = rAxisLabelProperties.
isStaggered();
741 sal_Int32 nLimitedSpaceForText = -1;
743 if (bIsBreakOfLabelsAllowed)
745 if (!m_aAxisProperties.m_bLimitSpaceForLabels)
748 nLimitedSpaceForText = nDeltaVector.
getX();
750 if (nScreenDistanceBetweenTicks > 0)
751 nLimitedSpaceForText = nScreenDistanceBetweenTicks;
754 nLimitedSpaceForText *= 2;
756 if( nLimitedSpaceForText > 0 )
758 sal_Int32 nReduce = (nLimitedSpaceForText*5)/100;
761 nLimitedSpaceForText -= nReduce;
768 m_aAxisProperties.m_bLimitSpaceForLabels =
false;
772 if ( m_aAxisProperties.m_bSwapXAndY && bIsVerticalAxis && rAxisLabelProperties.
m_fRotationAngleDegree == 0.0 )
775 m_aAxisProperties.m_bLimitSpaceForLabels =
false;
782 if( m_bUseTextLabels && !m_aAxisProperties.m_bComplexCategories )
783 pCategories = &m_aTextLabels;
786 if( !m_aAxisProperties.m_bSwapXAndY )
787 bLimitedHeight = fabs(aTextToTickDistance.getX()) > fabs(aTextToTickDistance.getY());
789 bLimitedHeight = fabs(aTextToTickDistance.getX()) < fabs(aTextToTickDistance.getY());
795 uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,
aPropNames,
u"CharColor");
798 *pColorAny >>= nColor;
800 uno::Any* pLimitedSpaceAny = PropertyMapper::getValuePointerForLimitedSpace(aPropValues,
aPropNames,bLimitedHeight);
802 const TickInfo* pPreviousVisibleTickInfo =
nullptr;
803 const TickInfo* pPREPreviousVisibleTickInfo =
nullptr;
807 ; pTickInfo = rTickIter.
nextInfo(), nTick++ )
809 const TickInfo* pLastVisibleNeighbourTickInfo = bIsStaggered ?
810 pPREPreviousVisibleTickInfo : pPreviousVisibleTickInfo;
813 if( nTick%rAxisLabelProperties.
m_nRhythm != 0 )
817 if( !pTickInfo->bPaintIt )
828 , pTickInfo->aTickScreenPosition ) )
833 bool bOverlapsAfterAutoStagger =
true;
834 if( !bIsStaggered && isAutoStaggeringOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis ) )
837 rAxisLabelProperties.
m_eStaggering = AxisLabelStaggering::StaggerEven;
838 pLastVisibleNeighbourTickInfo = pPREPreviousVisibleTickInfo;
839 if( !pLastVisibleNeighbourTickInfo ||
842 , pTickInfo->aTickScreenPosition ) )
843 bOverlapsAfterAutoStagger =
false;
846 if (bOverlapsAfterAutoStagger)
859 bool bHasExtraColor=
false;
863 aFixedNumberFormatter, pCategories, pTickInfo, isComplexCategoryAxis(),
864 nExtraColor, bHasExtraColor);
867 *pColorAny <<= bHasExtraColor?nExtraColor:nColor;
869 *pLimitedSpaceAny <<= sal_Int32(nLimitedSpaceForText*pTickInfo->nFactorForLimitedTextWidth);
871 B2DVector aTickScreenPos2D = pTickInfo->aTickScreenPosition;
872 aTickScreenPos2D += aTextToTickDistance;
873 awt::Point aAnchorScreenPosition2D(
874 static_cast<sal_Int32
>(aTickScreenPos2D.getX())
875 ,
static_cast<sal_Int32
>(aTickScreenPos2D.getY()));
878 if(!pTickInfo->xTextShape.is())
881 , aAnchorScreenPosition2D,
aLabel
882 , rAxisLabelProperties, m_aAxisProperties
883 ,
aPropNames, aPropValues, bIsHorizontalAxis );
885 if(!pTickInfo->xTextShape.is())
891 if (nLimitedSpaceForText > 0
899 if ( m_aAxisProperties.m_bComplexCategories )
905 removeTextShapesFromTicks();
916 bool bOverlapsAfterAutoStagger =
true;
917 if( !bIsStaggered && isAutoStaggeringOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis ) )
921 if( !isAutoRotatingOfLabelsAllowed(rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis)
922 || m_aAxisProperties.m_bTryStaggeringFirst )
925 rAxisLabelProperties.
m_eStaggering = AxisLabelStaggering::StaggerEven;
926 pLastVisibleNeighbourTickInfo = pPREPreviousVisibleTickInfo;
927 if( !pLastVisibleNeighbourTickInfo ||
930 , pTickInfo->aTickScreenPosition ) )
931 bOverlapsAfterAutoStagger =
false;
935 if (bOverlapsAfterAutoStagger)
938 if( isAutoRotatingOfLabelsAllowed(rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis) )
947 removeTextShapesFromTicks();
960 pPREPreviousVisibleTickInfo = pPreviousVisibleTickInfo;
961 pPreviousVisibleTickInfo = pTickInfo;
966bool VCartesianAxis::createTextShapesSimple(
980 if( m_bUseTextLabels && !m_aAxisProperties.m_bComplexCategories )
981 pCategories = &m_aTextLabels;
983 bool bLimitedHeight = fabs(aTextToTickDistance.getX()) > fabs(aTextToTickDistance.getY());
990 uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,
aPropNames,
u"CharColor");
993 *pColorAny >>= nColor;
995 uno::Any* pLimitedSpaceAny = PropertyMapper::getValuePointerForLimitedSpace(aPropValues,
aPropNames,bLimitedHeight);
997 const TickInfo* pPreviousVisibleTickInfo =
nullptr;
1001 ; pTickInfo = rTickIter.
nextInfo(), nTick++ )
1003 const TickInfo* pLastVisibleNeighbourTickInfo = pPreviousVisibleTickInfo;
1006 if( nTick%rAxisLabelProperties.
m_nRhythm != 0 )
1010 if( !pTickInfo->bPaintIt )
1021 , pTickInfo->aTickScreenPosition ) )
1032 bool bHasExtraColor=
false;
1036 aFixedNumberFormatter, pCategories, pTickInfo, isComplexCategoryAxis(),
1037 nExtraColor, bHasExtraColor);
1040 *pColorAny <<= bHasExtraColor?nExtraColor:nColor;
1041 if(pLimitedSpaceAny)
1042 *pLimitedSpaceAny <<= sal_Int32(-1*pTickInfo->nFactorForLimitedTextWidth);
1044 B2DVector aTickScreenPos2D = pTickInfo->aTickScreenPosition;
1045 aTickScreenPos2D += aTextToTickDistance;
1046 awt::Point aAnchorScreenPosition2D(
1047 static_cast<sal_Int32
>(aTickScreenPos2D.getX())
1048 ,
static_cast<sal_Int32
>(aTickScreenPos2D.getY()));
1051 if(!pTickInfo->xTextShape.is())
1053 , aAnchorScreenPosition2D,
aLabel
1054 , rAxisLabelProperties, m_aAxisProperties
1055 ,
aPropNames, aPropValues, bIsHorizontalAxis );
1056 if(!pTickInfo->xTextShape.is())
1068 if( isAutoRotatingOfLabelsAllowed(rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis) )
1077 removeTextShapesFromTicks();
1089 pPreviousVisibleTickInfo = pTickInfo;
1094double VCartesianAxis::getAxisIntersectionValue()
const
1096 if (m_aAxisProperties.m_pfMainLinePositionAtOtherAxis)
1097 return *m_aAxisProperties.m_pfMainLinePositionAtOtherAxis;
1099 double fMin = (
m_nDimensionIndex==1) ? m_pPosHelper->getLogicMinX() : m_pPosHelper->getLogicMinY();
1100 double fMax = (
m_nDimensionIndex==1) ? m_pPosHelper->getLogicMaxX() : m_pPosHelper->getLogicMaxY();
1102 return (m_aAxisProperties.m_eCrossoverType == css::chart::ChartAxisPosition_END) ? fMax : fMin;
1105double VCartesianAxis::getLabelLineIntersectionValue()
const
1107 if (m_aAxisProperties.m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_START)
1108 return (
m_nDimensionIndex==1) ? m_pPosHelper->getLogicMinX() : m_pPosHelper->getLogicMinY();
1110 if (m_aAxisProperties.m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_END)
1111 return (
m_nDimensionIndex==1) ? m_pPosHelper->getLogicMaxX() : m_pPosHelper->getLogicMaxY();
1113 return getAxisIntersectionValue();
1116double VCartesianAxis::getExtraLineIntersectionValue()
const
1118 if( !m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis )
1119 return std::numeric_limits<double>::quiet_NaN();
1121 double fMin = (
m_nDimensionIndex==1) ? m_pPosHelper->getLogicMinX() : m_pPosHelper->getLogicMinY();
1122 double fMax = (
m_nDimensionIndex==1) ? m_pPosHelper->getLogicMaxX() : m_pPosHelper->getLogicMaxY();
1124 if( *m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis <= fMin
1125 || *m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis >= fMax )
1126 return std::numeric_limits<double>::quiet_NaN();
1128 return *m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis;
1131B2DVector VCartesianAxis::getScreenPosition(
double fLogicX,
double fLogicY,
double fLogicZ )
const
1133 B2DVector aRet(0,0);
1137 drawing::Position3D aScenePos = m_pPosHelper->transformLogicToScene( fLogicX, fLogicY, fLogicZ,
true );
1140 if (m_xLogicTarget.is())
1144 , aScenePos,drawing::Direction3D(1,1,1), 0,
nullptr, aDummyPropertyNameMap);
1145 awt::Point a2DPos = xShape3DAnchor->getPosition();
1146 m_xLogicTarget->remove(xShape3DAnchor);
1147 aRet.setX( a2DPos.X );
1148 aRet.setY( a2DPos.Y );
1152 OSL_FAIL(
"cannot calculate screen position in VCartesianAxis::getScreenPosition");
1157 aRet.setX( aScenePos.PositionX );
1158 aRet.setY( aScenePos.PositionY );
1171 aRet.
aScreenPos = getScreenPosition( fLogicX_, fLogicY_, fLogicZ_ );
1187struct lcl_GreaterYPos
1197void VCartesianAxis::get2DAxisMainLine(
1198 B2DVector& rStart, B2DVector& rEnd,
AxisLabelAlignment& rAlignment,
double fCrossesOtherAxis )
const
1203 double const fMinX = m_pPosHelper->getLogicMinX();
1204 double const fMinY = m_pPosHelper->getLogicMinY();
1205 double const fMinZ = m_pPosHelper->getLogicMinZ();
1206 double const fMaxX = m_pPosHelper->getLogicMaxX();
1207 double const fMaxY = m_pPosHelper->getLogicMaxY();
1208 double const fMaxZ = m_pPosHelper->getLogicMaxZ();
1210 double fXOnXPlane = fMinX;
1211 double fXOther = fMaxX;
1212 int nDifferentValue = !m_pPosHelper->isMathematicalOrientationX() ? -1 : 1;
1213 if( !m_pPosHelper->isSwapXAndY() )
1217 if( nDifferentValue<0 )
1223 double fYOnYPlane = fMinY;
1224 double fYOther = fMaxY;
1225 nDifferentValue = !m_pPosHelper->isMathematicalOrientationY() ? -1 : 1;
1226 if( !m_pPosHelper->isSwapXAndY() )
1230 if( nDifferentValue<0 )
1236 double fZOnZPlane = fMaxZ;
1237 double fZOther = fMinZ;
1238 nDifferentValue = !m_pPosHelper->isMathematicalOrientationZ() ? -1 : 1;
1240 if( nDifferentValue<0 )
1246 double fXStart = fMinX;
1247 double fYStart = fMinY;
1248 double fZStart = fMinZ;
1251 double fZEnd = fZStart;
1255 if( fCrossesOtherAxis < fMinY )
1256 fCrossesOtherAxis = fMinY;
1257 else if( fCrossesOtherAxis > fMaxY )
1258 fCrossesOtherAxis = fMaxY;
1260 fYStart = fYEnd = fCrossesOtherAxis;
1261 fXEnd=m_pPosHelper->getLogicMaxX();
1265 if( AxisHelper::isAxisPositioningEnabled() )
1267 if( ::rtl::math::approxEqual( fYOther, fYStart) )
1268 fZStart = fZEnd = fZOnZPlane;
1270 fZStart = fZEnd = fZOther;
1274 rStart = getScreenPosition( fXStart, fYStart, fZStart );
1275 rEnd = getScreenPosition( fXEnd, fYEnd, fZEnd );
1277 double fDeltaX = rEnd.getX() - rStart.getX();
1278 double fDeltaY = rEnd.getY() - rStart.getY();
1281 tScreenPosAndLogicPosList aPosList { getScreenPosAndLogicPos( fMinX, fYOnYPlane, fZOther ), getScreenPosAndLogicPos( fMinX, fYOther, fZOnZPlane ) };
1283 if( fabs(fDeltaY) > fabs(fDeltaX) )
1287 std::sort( aPosList.begin(), aPosList.end(), lcl_LessXPos() );
1294 std::sort( aPosList.begin(), aPosList.end(), lcl_GreaterYPos() );
1298 fYStart = fYEnd = aBestPos.
fLogicY;
1299 fZStart = fZEnd = aBestPos.
fLogicZ;
1300 if( !m_pPosHelper->isMathematicalOrientationX() )
1307 if( fCrossesOtherAxis < fMinX )
1308 fCrossesOtherAxis = fMinX;
1309 else if( fCrossesOtherAxis > fMaxX )
1310 fCrossesOtherAxis = fMaxX;
1312 fXStart = fXEnd = fCrossesOtherAxis;
1313 fYEnd=m_pPosHelper->getLogicMaxY();
1317 if( AxisHelper::isAxisPositioningEnabled() )
1319 if( ::rtl::math::approxEqual( fXOther, fXStart) )
1320 fZStart = fZEnd = fZOnZPlane;
1322 fZStart = fZEnd = fZOther;
1326 rStart = getScreenPosition( fXStart, fYStart, fZStart );
1327 rEnd = getScreenPosition( fXEnd, fYEnd, fZEnd );
1329 double fDeltaX = rEnd.getX() - rStart.getX();
1330 double fDeltaY = rEnd.getY() - rStart.getY();
1333 tScreenPosAndLogicPosList aPosList { getScreenPosAndLogicPos( fXOnXPlane, fMinY, fZOther ), getScreenPosAndLogicPos( fXOther, fMinY, fZOnZPlane ) };
1335 if( fabs(fDeltaY) > fabs(fDeltaX) )
1339 std::sort( aPosList.begin(), aPosList.end(), lcl_LessXPos() );
1346 std::sort( aPosList.begin(), aPosList.end(), lcl_GreaterYPos() );
1350 fXStart = fXEnd = aBestPos.
fLogicX;
1351 fZStart = fZEnd = aBestPos.
fLogicZ;
1352 if( !m_pPosHelper->isMathematicalOrientationY() )
1359 fZEnd = m_pPosHelper->getLogicMaxZ();
1360 if( AxisHelper::isAxisPositioningEnabled() )
1362 if( !m_aAxisProperties.m_bSwapXAndY )
1364 if( fCrossesOtherAxis < fMinY )
1365 fCrossesOtherAxis = fMinY;
1366 else if( fCrossesOtherAxis > fMaxY )
1367 fCrossesOtherAxis = fMaxY;
1368 fYStart = fYEnd = fCrossesOtherAxis;
1370 if( ::rtl::math::approxEqual( fYOther, fYStart) )
1371 fXStart = fXEnd = fXOnXPlane;
1373 fXStart = fXEnd = fXOther;
1377 if( fCrossesOtherAxis < fMinX )
1378 fCrossesOtherAxis = fMinX;
1379 else if( fCrossesOtherAxis > fMaxX )
1380 fCrossesOtherAxis = fMaxX;
1381 fXStart = fXEnd = fCrossesOtherAxis;
1383 if( ::rtl::math::approxEqual( fXOther, fXStart) )
1384 fYStart = fYEnd = fYOnYPlane;
1386 fYStart = fYEnd = fYOther;
1391 if( !m_pPosHelper->isSwapXAndY() )
1393 fXStart = fXEnd = m_pPosHelper->isMathematicalOrientationX() ? m_pPosHelper->getLogicMaxX() : m_pPosHelper->getLogicMinX();
1394 fYStart = fYEnd = m_pPosHelper->isMathematicalOrientationY() ? m_pPosHelper->getLogicMinY() : m_pPosHelper->getLogicMaxY();
1398 fXStart = fXEnd = m_pPosHelper->isMathematicalOrientationX() ? m_pPosHelper->getLogicMinX() : m_pPosHelper->getLogicMaxX();
1399 fYStart = fYEnd = m_pPosHelper->isMathematicalOrientationY() ? m_pPosHelper->getLogicMaxY() : m_pPosHelper->getLogicMinY();
1404 rStart = getScreenPosition( fXStart, fYStart, fZStart );
1405 rEnd = getScreenPosition( fXEnd, fYEnd, fZEnd );
1407 double fDeltaX = rEnd.getX() - rStart.getX();
1410 tScreenPosAndLogicPosList aPosList { getScreenPosAndLogicPos( fXOther, fYOnYPlane, fMinZ ), getScreenPosAndLogicPos( fXOnXPlane, fYOther, fMinZ ) };
1412 std::sort( aPosList.begin(), aPosList.end(), lcl_GreaterYPos() );
1417 if( fDeltaX != 0.0 )
1433 if( !m_pPosHelper->isMathematicalOrientationZ() )
1436 fXStart = fXEnd = aBestPos.
fLogicX;
1437 fYStart = fYEnd = aBestPos.
fLogicY;
1442 rStart = getScreenPosition( fXStart, fYStart, fZStart );
1443 rEnd = getScreenPosition( fXEnd, fYEnd, fZEnd );
1445 if(m_nDimension==3 && !AxisHelper::isAxisPositioningEnabled() )
1448 if(!(m_nDimension==3 && AxisHelper::isAxisPositioningEnabled()) )
1451 double fDeltaX = rEnd.getX() - rStart.getX();
1452 double fDeltaY = rEnd.getY() - rStart.getY();
1466 if( ( fDeltaY<0 && m_aScale.Orientation == chart2::AxisOrientation_REVERSE ) ||
1467 ( fDeltaY>0 && m_aScale.Orientation == chart2::AxisOrientation_MATHEMATICAL ) )
1472 else if( fabs(fDeltaY) > fabs(fDeltaX) )
1484 if( ( fDeltaY<0 && m_aScale.Orientation == chart2::AxisOrientation_REVERSE ) ||
1485 ( fDeltaY>0 && m_aScale.Orientation == chart2::AxisOrientation_MATHEMATICAL ) )
1502 if( ( fDeltaX>0 && m_aScale.Orientation == chart2::AxisOrientation_REVERSE ) ||
1503 ( fDeltaX<0 && m_aScale.Orientation == chart2::AxisOrientation_MATHEMATICAL ) )
1512 return createTickFactory2D();
1518 B2DVector aStart, aEnd;
1519 get2DAxisMainLine(aStart, aEnd, aLabelAlign, getAxisIntersectionValue());
1521 B2DVector aLabelLineStart, aLabelLineEnd;
1522 get2DAxisMainLine(aLabelLineStart, aLabelLineEnd, aLabelAlign, getLabelLineIntersectionValue());
1523 m_aAxisProperties.maLabelAlignment = aLabelAlign;
1525 return new TickFactory2D( m_aScale, m_aIncrement, aStart, aEnd, aLabelLineStart-aStart );
1537 pTickInfo->bPaintIt = (pTickInfo->aTickScreenPosition != pPrevTickInfo->
aTickScreenPosition);
1538 pPrevTickInfo = pTickInfo;
1545 if( isComplexCategoryAxis() || isDateAxis() )
1547 sal_Int32
nCount = rTickInfos.size();
1548 for( sal_Int32 nN=0; nN<
nCount; nN++ )
1561sal_Int32 VCartesianAxis::estimateMaximumAutoMainIncrementCount()
1563 sal_Int32 nRet = 10;
1565 if( m_nMaximumTextWidthSoFar==0 && m_nMaximumTextHeightSoFar==0 )
1568 B2DVector aStart, aEnd;
1570 get2DAxisMainLine(aStart, aEnd, aLabelAlign, getAxisIntersectionValue());
1571 m_aAxisProperties.maLabelAlignment = aLabelAlign;
1573 sal_Int32 nMaxHeight =
static_cast<sal_Int32
>(fabs(aEnd.getY()-aStart.getY()));
1574 sal_Int32 nMaxWidth =
static_cast<sal_Int32
>(fabs(aEnd.getX()-aStart.getX()));
1576 sal_Int32 nTotalAvailable = nMaxHeight;
1577 sal_Int32 nSingleNeeded = m_nMaximumTextHeightSoFar;
1578 sal_Int32 nMaxSameLabel = 0;
1581 if (m_aAxisProperties.m_nAxisType != css::chart2::AxisType::DATE)
1583 FixedNumberFormatter aFixedNumberFormatterTest(m_xNumberFormatsSupplier, m_aAxisLabelProperties.m_nNumberFormatKey);
1584 OUString sPreviousValueLabel;
1585 sal_Int32 nSameLabel = 0;
1586 for (
auto const & nLabel: m_aAllTickInfos[0])
1589 bool bHasColor =
false;
1590 OUString sValueLabel = aFixedNumberFormatterTest.
getFormattedString(nLabel.fScaledTickValue, nColor, bHasColor);
1591 if (sValueLabel == sPreviousValueLabel)
1594 if (nSameLabel > nMaxSameLabel)
1595 nMaxSameLabel = nSameLabel;
1599 sPreviousValueLabel = sValueLabel;
1606 nTotalAvailable = nMaxWidth;
1607 nSingleNeeded = m_nMaximumTextWidthSoFar;
1610 if( nSingleNeeded>0 )
1611 nRet = nTotalAvailable/nSingleNeeded;
1613 if ( nMaxSameLabel > 0 )
1615 sal_Int32 nRetNoSameLabel = m_aAllTickInfos[0].size() / (nMaxSameLabel + 1);
1616 if ( nRet > nRetNoSameLabel )
1617 nRet = nRetNoSameLabel;
1625 if( !pTickFactory2D )
1628 if( isComplexCategoryAxis() )
1630 sal_Int32 nTextLevelCount = getTextLevelCount();
1631 B2DVector aCumulatedLabelsDistance(0,0);
1632 for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
1634 std::unique_ptr<TickIter> apTickIter(createLabelTickIterator(nTextLevel));
1637 double fRotationAngleDegree = m_aAxisLabelProperties.m_fRotationAngleDegree;
1642 if( m_aAxisProperties.m_bSwapXAndY )
1643 fRotationAngleDegree = 90.0;
1645 fRotationAngleDegree = 0.0;
1649 fRotationAngleDegree);
1655 if( !m_aAllTickInfos.empty() )
1657 LabelIterator aInnerIter( m_aAllTickInfos[0], rAxisLabelProperties.
m_eStaggering,
true );
1658 LabelIterator aOuterIter( m_aAllTickInfos[0], rAxisLabelProperties.
m_eStaggering,
false );
1667void VCartesianAxis::createDataTableShape(std::unique_ptr<TickFactory2D>
const& rpTickFactory2D)
1671 if (!m_pDataTableView || !m_aAxisProperties.m_bDisplayDataTable)
1674 m_pDataTableView->initializeShapes(m_xDataTableTarget);
1678 rpTickFactory2D->updateScreenValues(m_aAllTickInfos);
1680 sal_Int32 nDistance = -1;
1682 std::unique_ptr<TickIter> apTickIter(createLabelTickIterator(0));
1685 nDistance = TickFactory2D::getTickScreenDistance(*apTickIter);
1686 if (getTextLevelCount() > 1)
1692 m_pDataTableView->createShapes(aStart, aEnd, nDistance);
1696void VCartesianAxis::createLabels()
1698 if( !prepareShapeCreation() )
1701 std::unique_ptr<TickFactory2D> apTickFactory2D(createTickFactory2D());
1703 createDataTableShape(apTickFactory2D);
1706 if (!m_aAxisProperties.m_bDisplayLabels)
1714 hideIdenticalScreenValues( m_aAllTickInfos );
1716 removeTextShapesFromTicks();
1719 sal_Int32 nTextLevelCount = getTextLevelCount();
1720 sal_Int32 nScreenDistanceBetweenTicks = -1;
1721 for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
1723 std::unique_ptr< TickIter > apTickIter(createLabelTickIterator( nTextLevel ));
1728 nScreenDistanceBetweenTicks = TickFactory2D::getTickScreenDistance(*apTickIter);
1729 if( nTextLevelCount>1 )
1730 nScreenDistanceBetweenTicks*=2;
1734 if( m_aAxisProperties.m_bComplexCategories )
1738 if( nTextLevel > 0 )
1741 if( m_aAxisProperties.m_bSwapXAndY )
1747 AxisLabelProperties& rAxisLabelProperties = m_aAxisProperties.m_bComplexCategories ? aComplexProps : m_aAxisLabelProperties;
1748 while (!createTextShapes(m_xTextTarget, *apTickIter, rAxisLabelProperties,
1749 pTickFactory2D, nScreenDistanceBetweenTicks))
1754 doStaggeringOfLabels( m_aAxisLabelProperties, pTickFactory2D );
1756 if (m_pDataTableView)
1758 sal_Int32
x = m_xTextTarget->getPosition().X;
1759 sal_Int32
y = m_xTextTarget->getPosition().Y;
1760 sal_Int32 height = m_xTextTarget->getSize().Height;
1761 m_pDataTableView->changePosition(
x,
y + height);
1765void VCartesianAxis::createMaximumLabels()
1767 m_bRecordMaximumTextSize =
true;
1770 if( !prepareShapeCreation() )
1774 if (!m_aAxisProperties.m_bDisplayLabels)
1777 std::unique_ptr<TickFactory2D> apTickFactory2D(createTickFactory2D());
1788 aAxisLabelProperties.
m_eStaggering = AxisLabelStaggering::StaggerEven;
1792 sal_Int32 nTextLevelCount = getTextLevelCount();
1793 for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
1795 std::unique_ptr< TickIter > apTickIter(createMaximumLabelTickIterator( nTextLevel ));
1798 while (!createTextShapes(m_xTextTarget, *apTickIter, aAxisLabelProperties,
1799 pTickFactory2D, -1))
1804 doStaggeringOfLabels( aAxisLabelProperties, pTickFactory2D );
1807void VCartesianAxis::updatePositions()
1810 if (!m_aAxisProperties.m_bDisplayLabels)
1813 std::unique_ptr<TickFactory2D> apTickFactory2D(createTickFactory2D());
1820 for (
auto const& tickInfos : m_aAllTickInfos)
1822 for (
auto const& tickInfo : tickInfos)
1825 if( xShape2DText.is() )
1828 B2DVector aTickScreenPos2D(tickInfo.aTickScreenPosition);
1829 aTickScreenPos2D += aTextToTickDistance;
1830 awt::Point aAnchorScreenPosition2D(
1831 static_cast<sal_Int32
>(aTickScreenPos2D.getX())
1832 ,
static_cast<sal_Int32
>(aTickScreenPos2D.getY()));
1834 double fRotationAngleDegree = m_aAxisLabelProperties.m_fRotationAngleDegree;
1839 fRotationAngleDegree = 0.0;
1841 fRotationAngleDegree = 90;
1846 uno::Any aATransformation = ShapeFactory::makeTransformation(aAnchorScreenPosition2D, fRotationAnglePi);
1851 xShape2DText->SvxShape::setPropertyValue(
"Transformation", aATransformation );
1853 catch(
const uno::Exception& )
1859 LabelPositionHelper::correctPositionForRotation( xShape2DText
1860 , m_aAxisProperties.maLabelAlignment.meAlignment, fRotationAngleDegree, m_aAxisProperties.m_bComplexCategories );
1866 doStaggeringOfLabels( m_aAxisLabelProperties, pTickFactory2D );
1871 sal_Int32 nPointCount = rTickInfos.size();
1872 drawing::PointSequenceSequence aPoints(2*nPointCount);
1875 for (
auto const& tickInfo : rTickInfos)
1877 if( !tickInfo.bPaintIt )
1880 bool bTicksAtLabels = ( m_aAxisProperties.m_eTickmarkPos != css::chart::ChartAxisMarkPosition_AT_AXIS );
1881 double fInnerDirectionSign = m_aAxisProperties.maLabelAlignment.mfInnerTickDirection;
1882 if( bTicksAtLabels && m_aAxisProperties.m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_END )
1883 fInnerDirectionSign *= -1.0;
1884 bTicksAtLabels = bTicksAtLabels || bOnlyAtLabels;
1887 , fInnerDirectionSign , rTickmarkProperties, bTicksAtLabels );
1889 if( !bOnlyAtLabels && m_aAxisProperties.m_eTickmarkPos == css::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS )
1891 , m_aAxisProperties.maLabelAlignment.mfInnerTickDirection, rTickmarkProperties, !bTicksAtLabels );
1893 aPoints.realloc(nN);
1894 ShapeFactory::createLine2D( m_xGroupShape_Shapes, aPoints
1898void VCartesianAxis::createShapes()
1900 if( !prepareShapeCreation() )
1906 std::unique_ptr<TickFactory2D> apTickFactory2D(createTickFactory2D());
1910 if( isComplexCategoryAxis() )
1913 createAllTickInfosFromComplexCategories( aComplexTickInfos,
true );
1915 hideIdenticalScreenValues( aComplexTickInfos );
1917 std::vector<TickmarkProperties> aTickmarkPropertiesList;
1918 static const bool bIncludeSpaceBetweenTickAndText =
false;
1920 sal_Int32 nTextLevelCount = getTextLevelCount();
1921 for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
1923 std::unique_ptr< TickIter > apTickIter(createLabelTickIterator( nTextLevel ));
1926 double fRotationAngleDegree = m_aAxisLabelProperties.m_fRotationAngleDegree;
1927 if( nTextLevel > 0 )
1930 if( m_aAxisProperties.m_bSwapXAndY )
1931 fRotationAngleDegree = 90.0;
1933 fRotationAngleDegree = 0.0;
1937 fRotationAngleDegree));
1938 sal_Int32 nCurrentLength =
static_cast<sal_Int32
>(aLabelsDistance.getLength());
1939 aTickmarkPropertiesList.push_back( m_aAxisProperties.makeTickmarkPropertiesForComplexCategories( nOffset + nCurrentLength, 0 ) );
1940 nOffset += nCurrentLength;
1944 sal_Int32 nTickmarkPropertiesCount = aTickmarkPropertiesList.size();
1945 TickInfoArraysType::iterator aDepthIter = aComplexTickInfos.begin();
1946 const TickInfoArraysType::const_iterator aDepthEnd = aComplexTickInfos.end();
1947 for( sal_Int32 nDepth=0; aDepthIter != aDepthEnd && nDepth < nTickmarkPropertiesCount; ++aDepthIter, nDepth++ )
1949 if(nDepth==0 && !m_aAxisProperties.m_nMajorTickmarks)
1951 createTickMarkLineShapes( *aDepthIter, aTickmarkPropertiesList[nDepth], *pTickFactory2D,
true );
1957 if( m_aScale.m_bShiftedCategoryPosition )
1959 pTickFactory2D->
getAllTicks( aUnshiftedTickInfos );
1961 hideIdenticalScreenValues( aUnshiftedTickInfos );
1963 TickInfoArraysType& rAllTickInfos = m_aScale.m_bShiftedCategoryPosition ? aUnshiftedTickInfos : m_aAllTickInfos;
1965 if (rAllTickInfos.empty())
1968 sal_Int32 nDepth = 0;
1969 sal_Int32 nTickmarkPropertiesCount = m_aAxisProperties.m_aTickmarkPropertiesList.size();
1970 for(
auto& rTickInfos : rAllTickInfos )
1972 if (nDepth == nTickmarkPropertiesCount)
1975 createTickMarkLineShapes( rTickInfos, m_aAxisProperties.m_aTickmarkPropertiesList[nDepth], *pTickFactory2D,
false );
1982 drawing::PointSequenceSequence aPoints(1);
1983 apTickFactory2D->createPointSequenceForAxisMainLine( aPoints );
1985 m_xGroupShape_Shapes, aPoints
1986 , &m_aAxisProperties.m_aLineProperties );
1991 if( !AxisHelper::isAxisPositioningEnabled() )
1993 double fExtraLineCrossesOtherAxis = getExtraLineIntersectionValue();
1994 if (!std::isnan(fExtraLineCrossesOtherAxis))
1996 B2DVector aStart, aEnd;
1998 get2DAxisMainLine(aStart, aEnd, aLabelAlign, fExtraLineCrossesOtherAxis);
1999 m_aAxisProperties.maLabelAlignment = aLabelAlign;
2000 drawing::PointSequenceSequence aPoints{{
2001 {
static_cast<sal_Int32
>(aStart.getX()),
static_cast<sal_Int32
>(aStart.getY())},
2002 {
static_cast<sal_Int32
>(aEnd.getX()),
static_cast<sal_Int32
>(aEnd.getY())} }};
2003 ShapeFactory::createLine2D(
2004 m_xGroupShape_Shapes, aPoints, &m_aAxisProperties.m_aLineProperties );
2012void VCartesianAxis::createDataTableView(std::vector<std::unique_ptr<VSeriesPlotter>>& rSeriesPlotterList,
2015 css::uno::Reference<css::uno::XComponentContext>
const& rComponentContext)
2017 if (!m_aAxisProperties.m_bDisplayDataTable)
2020 m_pDataTableView.reset(
new DataTableView(xChartDoc, m_aAxisProperties.m_xDataTableModel, rComponentContext, m_aAxisProperties.m_bDataTableAlignAxisValuesWithColumns));
2021 m_pDataTableView->initializeValues(rSeriesPlotterList);
2022 m_xNumberFormatsSupplier = xNumberFormatsSupplier;
PureTickIter m_aPureTickIter
const AxisLabelStaggering m_eAxisLabelStaggering
std::vector< size_t > m_aValidIndices
TickInfoArrayType & m_rTickInfoVector
sal_Int32 m_nDimensionIndex
virtual void SAL_CALL setString(const OUString &aString) override
virtual css::awt::Point SAL_CALL getPosition() override
virtual css::awt::Size SAL_CALL getSize() override
virtual SvxTextForwarder * GetTextForwarder() override
virtual sal_Int32 GetLineCount(sal_Int32 nPara) const=0
virtual void GetLineBoundaries(sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nParagraph, sal_Int32 nLine) const=0
virtual sal_Int32 GetParagraphCount() const=0
virtual bool GetWordIndices(sal_Int32 nPara, sal_Int32 nIndex, sal_Int32 &rStart, sal_Int32 &rEnd) const=0
void rotate(double fRadiant)
void translate(double fX, double fY)
bool isInside(const Tuple2D< TYPE > &rTuple) const
DataTableView is responsible to create the table object, set the cell properties accordingly to the m...
static void correctPositionForRotation(const rtl::Reference< SvxShapeText > &xShape2DText, LabelAlignment eLabelAlignment, const double fRotationAngle, bool bRotateAroundCenter)
PlottingPositionHelper * m_pPosHelper
static void setMultiProperties(const tNameSequence &rNames, const tAnySequence &rValues, SvxShape &xTarget)
static void setShapeName(const rtl::Reference< SvxShape > &xShape, const OUString &rName)
static OUString getStackedString(const OUString &rString, bool bStacked)
static css::awt::Size getSizeAfterRotation(SvxShape &rShape, double fRotationAngleDegree)
static rtl::Reference< SvxShapeText > createText(const rtl::Reference< SvxShapeGroupAnyD > &xTarget2D, const OUString &rText, const tNameSequence &rPropNames, const tAnySequence &rPropValues, const css::uno::Any &rATransformation)
static css::uno::Any makeTransformation(const css::awt::Point &rScreenPosition2D, double fRotationAnglePi=0.0)
bool isHorizontalAxis() const
const ::basegfx::B2DVector & getXaxisEndPos() const
void addPointSequenceForTickLine(css::drawing::PointSequenceSequence &rPoints, sal_Int32 nSequenceIndex, double fScaledLogicTickValue, double fInnerDirectionSign, const TickmarkProperties &rTickmarkProperties, bool bPlaceAtLabels) const
::basegfx::B2DVector getDistanceAxisTickToText(const AxisProperties &rAxisProperties, bool bIncludeFarAwayDistanceIfSo=false, bool bIncludeSpaceBetweenTickAndText=true) const
bool isVerticalAxis() const
void updateScreenValues(TickInfoArraysType &rAllTickInfos) const
Determine the screen positions of all ticks based on their numeric values.
const ::basegfx::B2DVector & getXaxisStartPos() const
void getAllTicks(TickInfoArraysType &rAllTickInfos) const
virtual TickInfo * nextInfo()=0
virtual TickInfo * firstInfo()=0
VCartesianAxis(const AxisProperties &rAxisProperties, const css::uno::Reference< css::util::XNumberFormatsSupplier > &xNumberFormatsSupplier, sal_Int32 nDimensionIndex, sal_Int32 nDimensionCount, PlottingPositionHelper *pPosHelper=nullptr)
virtual ~VCartesianAxis() override
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< XInterface > xTarget
double getLength(const B2DPolygon &rCandidate)
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
constexpr double deg2rad(double v)
OOO_DLLPUBLIC_CHARTTOOLS::basegfx::B2IRectangle makeRectangle(const css::awt::Point &rPosition, const css::awt::Size &rSize)
static OUString getTextLabelString(const FixedNumberFormatter &rFixedNumberFormatter, const uno::Sequence< OUString > *pCategories, const TickInfo *pTickInfo, bool bComplexCat, Color &rExtraColor, bool &rHasExtraColor)
static void getAxisLabelProperties(tNameSequence &rPropNames, tAnySequence &rPropValues, const AxisProperties &rAxisProp, const AxisLabelProperties &rAxisLabelProp, sal_Int32 nLimitedSpaceForText, bool bLimitedHeight)
static bool lcl_doesShapeOverlapWithTickmark(SvxShape &rShape, double fRotationAngleDegree, const basegfx::B2DVector &rTickScreenPosition)
static void lcl_hideIdenticalScreenValues(TickIter &rTickIter)
static bool lcl_hasWordBreak(const rtl::Reference< SvxShapeText > &xShape)
static void lcl_shiftLabels(TickIter &rIter, const B2DVector &rStaggerDistance)
css::uno::Sequence< OUString > tNameSequence
static B2DVector lcl_getLabelsDistance(TickIter &rIter, const B2DVector &rDistanceTickToText, double fRotationAngleDegree)
std::vector< TickInfoArrayType > TickInfoArraysType
std::unordered_map< OUString, OUString > tPropertyNameMap
static bool doesOverlap(const rtl::Reference< SvxShapeText > &xShape1, const rtl::Reference< SvxShapeText > &xShape2, double fRotationAngleDegree)
css::uno::Sequence< css::uno::Any > tAnySequence
@ CuboidPlanePosition_Left
@ CuboidPlanePosition_Back
@ CuboidPlanePosition_Bottom
std::vector< TickInfo > TickInfoArrayType
static rtl::Reference< SvxShapeText > createSingleLabel(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const awt::Point &rAnchorScreenPosition2D, const OUString &rLabel, const AxisLabelProperties &rAxisLabelProperties, const AxisProperties &rAxisProperties, const tNameSequence &rPropNames, const tAnySequence &rPropValues, const bool bIsHorizontalAxis)
static void lcl_ResizeTextShapeToFitAvailableSpace(SvxShapeText &rShape2DText, const AxisLabelProperties &rAxisLabelProperties, std::u16string_view rLabel, const tNameSequence &rPropNames, const tAnySequence &rPropValues, const bool bIsHorizontalAxis)
std::vector< VCartesianAxis::ScreenPosAndLogicPos > tScreenPosAndLogicPosList
static void removeShapesAtWrongRhythm(TickIter &rIter, sal_Int32 nCorrectRhythm, sal_Int32 nMaxTickToCheck, const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
static void lcl_getRotatedPolygon(B2DPolygon &aPoly, const ::basegfx::B2DRectangle &aRect, const awt::Point &aPos, const double fRotationAngleDegree)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
const PropertyStruct aPropNames[]
double mfInnerTickDirection
which direction the labels are to be drawn.
LabelAlignment meAlignment
which direction the inner tickmarks are to be drawn.
css::awt::Size m_aFontReferenceSize
AxisLabelStaggering m_eStaggering
sal_Int32 m_nNumberFormatKey
double m_fRotationAngleDegree
css::awt::Rectangle m_aMaximumSpaceForLabels
bool m_bComplexCategories
AxisLabelAlignment maLabelAlignment
bool m_bLimitSpaceForLabels
rtl::Reference<::chart::Axis > m_xAxisModel
double getUnscaledTickValue() const
Return a value associated with the tick mark.
::basegfx::B2DVector aTickScreenPosition
sal_Int32 nFactorForLimitedTextWidth
rtl::Reference< SvxShapeText > xTextShape
VLineProperties aLineProperties
::basegfx::B2DVector aScreenPos