summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngrid Halama <iha@openoffice.org>2009-12-15 16:30:15 +0100
committerIngrid Halama <iha@openoffice.org>2009-12-15 16:30:15 +0100
commit91f22fc22a92557dd823ac63456743736fd27ec0 (patch)
treed89d26ed8b9f009ad02902160fdc0af82815b939
parent4d5f3c429b4391d63cab1af8b070b04f5787f5c4 (diff)
chartmultiline: #i82971# complex categories (part2 - hierarchical axis label display)
-rw-r--r--chart2/source/inc/ExplicitCategoriesProvider.hxx23
-rw-r--r--chart2/source/tools/DiagramHelper.cxx2
-rw-r--r--chart2/source/tools/ExplicitCategoriesProvider.cxx56
-rw-r--r--chart2/source/view/axes/TickmarkHelper.cxx109
-rw-r--r--chart2/source/view/axes/TickmarkHelper.hxx39
-rw-r--r--chart2/source/view/axes/VAxisBase.cxx41
-rw-r--r--chart2/source/view/axes/VAxisBase.hxx3
-rw-r--r--chart2/source/view/axes/VAxisProperties.cxx18
-rw-r--r--chart2/source/view/axes/VAxisProperties.hxx9
-rw-r--r--chart2/source/view/axes/VCartesianAxis.cxx611
-rw-r--r--chart2/source/view/axes/VCartesianAxis.hxx17
-rw-r--r--chart2/source/view/axes/VCartesianCoordinateSystem.cxx10
-rw-r--r--chart2/source/view/axes/VPolarAngleAxis.cxx9
-rw-r--r--chart2/source/view/axes/VPolarAngleAxis.hxx2
-rw-r--r--chart2/source/view/axes/VPolarGrid.cxx2
-rw-r--r--chart2/source/view/axes/VPolarRadiusAxis.cxx3
-rw-r--r--chart2/source/view/charttypes/AreaChart.cxx17
-rw-r--r--chart2/source/view/charttypes/AreaChart.hxx3
-rw-r--r--chart2/source/view/charttypes/VSeriesPlotter.cxx21
-rw-r--r--chart2/source/view/inc/PropertyMapper.hxx5
-rw-r--r--chart2/source/view/main/ChartView.cxx10
-rw-r--r--chart2/source/view/main/PropertyMapper.cxx8
22 files changed, 692 insertions, 326 deletions
diff --git a/chart2/source/inc/ExplicitCategoriesProvider.hxx b/chart2/source/inc/ExplicitCategoriesProvider.hxx
index 965013b2bb6c..0ba0d92876f0 100644
--- a/chart2/source/inc/ExplicitCategoriesProvider.hxx
+++ b/chart2/source/inc/ExplicitCategoriesProvider.hxx
@@ -38,9 +38,20 @@
#include <com/sun/star/frame/XModel.hpp>
#include "charttoolsdllapi.hxx"
+#include <vector>
+
namespace chart
{
+struct OOO_DLLPUBLIC_CHARTTOOLS ComplexCategory
+{
+ rtl::OUString Text;
+ sal_Int32 Count;
+
+ ComplexCategory( const rtl::OUString& rText, sal_Int32 nCount ) : Text( rText ), Count (nCount)
+ {}
+};
+
class OOO_DLLPUBLIC_CHARTTOOLS ExplicitCategoriesProvider
{
public:
@@ -49,11 +60,12 @@ public:
, const ::com::sun::star::uno::Reference<
::com::sun::star::frame::XModel >& xChartModel
);
- SAL_DLLPRIVATE virtual ~ExplicitCategoriesProvider();
+ virtual ~ExplicitCategoriesProvider();
+
+ void init();
- //XTextualDataSequence
- SAL_DLLPRIVATE virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getTextualData()
- throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > getSimpleCategories();
+ ::std::vector< ComplexCategory > getCategoriesByLevel( sal_Int32 nLevel );
static ::rtl::OUString getCategoryByIndex(
const ::com::sun::star::uno::Reference<
@@ -66,7 +78,8 @@ public:
sal_Int32 getCategoryLevelCount() const;
private: //member
- ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aExplicitCategories;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aExplicitCategories;
+ ::std::vector< ::std::vector< ComplexCategory > > m_aComplexCats;
bool volatile m_bDirty;
::com::sun::star::uno::WeakReference<
diff --git a/chart2/source/tools/DiagramHelper.cxx b/chart2/source/tools/DiagramHelper.cxx
index 552c2b5304b5..60dcf1c00557 100644
--- a/chart2/source/tools/DiagramHelper.cxx
+++ b/chart2/source/tools/DiagramHelper.cxx
@@ -1024,7 +1024,7 @@ Sequence< rtl::OUString > DiagramHelper::getExplicitSimpleCategories(
if( xCategories.is() )
{
ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSys, xChartModel );
- aRet = aExplicitCategoriesProvider.getTextualData();
+ aRet = aExplicitCategoriesProvider.getSimpleCategories();
}
}
}
diff --git a/chart2/source/tools/ExplicitCategoriesProvider.cxx b/chart2/source/tools/ExplicitCategoriesProvider.cxx
index 64137a20ebb2..f670b68d9ecb 100644
--- a/chart2/source/tools/ExplicitCategoriesProvider.cxx
+++ b/chart2/source/tools/ExplicitCategoriesProvider.cxx
@@ -89,7 +89,6 @@ ExplicitCategoriesProvider::ExplicitCategoriesProvider( const Reference< chart2:
{
Sequence< Reference< data::XLabeledDataSequence> > aColumns = xColumnCategoriesSource->getDataSequences();
Sequence< Reference< data::XLabeledDataSequence> > aRows = xRowCategoriesSource->getDataSequences();
- //m_aSplitCategoriesList;
sal_Int32 nColumnCount = aColumns.getLength();
sal_Int32 nRowCount = aRows.getLength();
@@ -142,15 +141,6 @@ sal_Int32 ExplicitCategoriesProvider::getCategoryLevelCount() const
return nCount;
}
-struct ComplexCategory
-{
- OUString Text;
- sal_Int32 Count;
-
- ComplexCategory( const OUString& rText, sal_Int32 nCount ) : Text( rText ), Count (nCount)
- {}
-};
-
std::vector<sal_Int32> lcl_getLimitingBorders( const std::vector< ComplexCategory >& rComplexCategories )
{
std::vector<sal_Int32> aLimitingBorders;
@@ -168,7 +158,7 @@ std::vector<sal_Int32> lcl_getLimitingBorders( const std::vector< ComplexCategor
std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector(
const uno::Reference< data::XDataSequence >& xDataSequence
- , const std::vector<sal_Int32>& rLimitingBorders )
+ , const std::vector<sal_Int32>& rLimitingBorders, bool bCreateSingleCategories )
{
std::vector< ComplexCategory > aResult;
OSL_ASSERT( xDataSequence.is());
@@ -195,7 +185,7 @@ std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector(
for( sal_Int32 nN=0; nN<nMaxCount; nN++ )
{
OUString aCurrent = aStrings[nN];
- if( ::std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() )
+ if( bCreateSingleCategories || ::std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() )
{
aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) );
nCurrentCount=1;
@@ -234,20 +224,19 @@ sal_Int32 lcl_getCategoryCount( std::vector< ComplexCategory >& rComplexCategori
return nCount;
}
-//XTextualDataSequence
-Sequence< ::rtl::OUString > SAL_CALL ExplicitCategoriesProvider::getTextualData() throw( uno::RuntimeException)
+void ExplicitCategoriesProvider::init()
{
if( m_bDirty )
{
+ m_aExplicitCategories.realloc(0);
+ m_aComplexCats.clear();//not one per index
+
if( m_xOriginalCategories.is() )
{
if( !hasComplexCategories() )
m_aExplicitCategories = DataSequenceToStringSequence(m_xOriginalCategories->getValues());
else
{
- std::vector< std::vector< ComplexCategory > > aComplexCats;//not one per index
-
- //std::vector< std::vector< rtl::OUString > > aCats;
sal_Int32 nLCount = m_aSplitCategoriesList.getLength();
for( sal_Int32 nL = 0; nL < nLCount; nL++ )
{
@@ -256,24 +245,23 @@ Sequence< ::rtl::OUString > SAL_CALL ExplicitCategoriesProvider::getTextualData(
{
std::vector<sal_Int32> aLimitingBorders;
if(nL>0)
- aLimitingBorders = lcl_getLimitingBorders( aComplexCats.back() );
- aComplexCats.push_back( lcl_DataSequenceToComplexCategoryVector( xLabeledDataSequence->getValues(), aLimitingBorders ) );
- //aCats.push_back( ContainerHelper::SequenceToVector( DataSequenceToStringSequence(xLabeledDataSequence->getValues() ) ) );
+ aLimitingBorders = lcl_getLimitingBorders( m_aComplexCats.back() );
+ m_aComplexCats.push_back( lcl_DataSequenceToComplexCategoryVector( xLabeledDataSequence->getValues(), aLimitingBorders, nL==(nLCount-1) ) );
}
}
- std::vector< std::vector< ComplexCategory > >::iterator aOuterIt( aComplexCats.begin() );
- std::vector< std::vector< ComplexCategory > >::const_iterator aOuterEnd( aComplexCats.end() );
+ std::vector< std::vector< ComplexCategory > >::iterator aOuterIt( m_aComplexCats.begin() );
+ std::vector< std::vector< ComplexCategory > >::const_iterator aOuterEnd( m_aComplexCats.end() );
//ensure that the category count is the same on each level
sal_Int32 nMaxCategoryCount = 0;
{
- for( aOuterIt=aComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
+ for( aOuterIt=m_aComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
{
sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
nMaxCategoryCount = std::max( nCurrentCount, nMaxCategoryCount );
}
- for( aOuterIt=aComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
+ for( aOuterIt=m_aComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt )
{
sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt );
if( nCurrentCount< nMaxCategoryCount )
@@ -286,7 +274,7 @@ Sequence< ::rtl::OUString > SAL_CALL ExplicitCategoriesProvider::getTextualData(
//create a list with an element for every index
std::vector< std::vector< ComplexCategory > > aComplexCatsPerIndex;
- for( aOuterIt=aComplexCats.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
+ for( aOuterIt=m_aComplexCats.begin() ; aOuterIt != aOuterEnd; ++aOuterIt )
{
std::vector< ComplexCategory > aSingleLevel;
std::vector< ComplexCategory >::iterator aIt( aOuterIt->begin() );
@@ -328,9 +316,25 @@ Sequence< ::rtl::OUString > SAL_CALL ExplicitCategoriesProvider::getTextualData(
m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel );
m_bDirty = false;
}
+}
+
+
+Sequence< ::rtl::OUString > ExplicitCategoriesProvider::getSimpleCategories()
+{
+ init();
return m_aExplicitCategories;
}
+std::vector< ComplexCategory > ExplicitCategoriesProvider::getCategoriesByLevel( sal_Int32 nLevel )
+{
+ std::vector< ComplexCategory > aRet;
+ init();
+ sal_Int32 nMaxIndex = m_aComplexCats.size()-1;
+ if( nLevel >= 0 && nLevel <= nMaxIndex )
+ aRet = m_aComplexCats[nMaxIndex-nLevel];
+ return aRet;
+}
+
// static
OUString ExplicitCategoriesProvider::getCategoryByIndex(
const Reference< XCoordinateSystem >& xCooSysModel
@@ -340,7 +344,7 @@ OUString ExplicitCategoriesProvider::getCategoryByIndex(
if( xCooSysModel.is())
{
ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSysModel, xChartModel );
- Sequence< OUString > aCategories( aExplicitCategoriesProvider.getTextualData());
+ Sequence< OUString > aCategories( aExplicitCategoriesProvider.getSimpleCategories());
if( nIndex < aCategories.getLength())
return aCategories[ nIndex ];
}
diff --git a/chart2/source/view/axes/TickmarkHelper.cxx b/chart2/source/view/axes/TickmarkHelper.cxx
index 81dc5786653e..30697b1a31f2 100644
--- a/chart2/source/view/axes/TickmarkHelper.cxx
+++ b/chart2/source/view/axes/TickmarkHelper.cxx
@@ -51,6 +51,7 @@ TickInfo::TickInfo()
, aTickScreenPosition(0.0,0.0)
, bPaintIt( true )
, xTextShape( NULL )
+, nFactorForLimitedTextWidth(1)
{
}
@@ -62,10 +63,45 @@ void TickInfo::updateUnscaledValue( const uno::Reference< XScaling >& xInverseSc
this->fUnscaledTickValue = this->fScaledTickValue;
}
-TickIter::TickIter( const uno::Sequence< uno::Sequence< double > >& rTicks
+sal_Int32 TickInfo::getScreenDistanceBetweenTicks( const TickInfo& rOherTickInfo ) const
+{
+ //return the positive distance between the two first tickmarks in screen values
+
+ B2DVector aDistance = rOherTickInfo.aTickScreenPosition - aTickScreenPosition;
+ sal_Int32 nRet = static_cast<sal_Int32>(aDistance.getLength());
+ if(nRet<0)
+ nRet *= -1;
+ return nRet;
+}
+
+PureTickIter::PureTickIter( ::std::vector< TickInfo >& rTickInfoVector )
+ : m_rTickVector(rTickInfoVector)
+ , m_aTickIter(m_rTickVector.begin())
+{
+}
+PureTickIter::~PureTickIter()
+{
+}
+TickInfo* PureTickIter::firstInfo()
+{
+ m_aTickIter = m_rTickVector.begin();
+ if(m_aTickIter!=m_rTickVector.end())
+ return &*m_aTickIter;
+ return 0;
+}
+TickInfo* PureTickIter::nextInfo()
+{
+ m_aTickIter++;
+ if(m_aTickIter!=m_rTickVector.end())
+ return &*m_aTickIter;
+ return 0;
+}
+
+EquidistantTickIter::EquidistantTickIter( const uno::Sequence< uno::Sequence< double > >& rTicks
, const ExplicitIncrementData& rIncrement
, sal_Int32 nMinDepth, sal_Int32 nMaxDepth )
- : m_pSimpleTicks(&rTicks), m_pInfoTicks(NULL)
+ : m_pSimpleTicks(&rTicks)
+ , m_pInfoTicks(0)
, m_rIncrement(rIncrement)
, m_nMinDepth(0), m_nMaxDepth(0)
, m_nTickCount(0), m_pnPositions(NULL)
@@ -75,10 +111,11 @@ TickIter::TickIter( const uno::Sequence< uno::Sequence< double > >& rTicks
initIter( nMinDepth, nMaxDepth );
}
-TickIter::TickIter( ::std::vector< ::std::vector< TickInfo > >& rTicks
+EquidistantTickIter::EquidistantTickIter( ::std::vector< ::std::vector< TickInfo > >& rTicks
, const ExplicitIncrementData& rIncrement
, sal_Int32 nMinDepth, sal_Int32 nMaxDepth )
- : m_pSimpleTicks(NULL), m_pInfoTicks(&rTicks)
+ : m_pSimpleTicks(NULL)
+ , m_pInfoTicks(&rTicks)
, m_rIncrement(rIncrement)
, m_nMinDepth(0), m_nMaxDepth(0)
, m_nTickCount(0), m_pnPositions(NULL)
@@ -88,7 +125,7 @@ TickIter::TickIter( ::std::vector< ::std::vector< TickInfo > >& rTicks
initIter( nMinDepth, nMaxDepth );
}
-void TickIter::initIter( sal_Int32 /*nMinDepth*/, sal_Int32 nMaxDepth )
+void EquidistantTickIter::initIter( sal_Int32 /*nMinDepth*/, sal_Int32 nMaxDepth )
{
m_nMaxDepth = nMaxDepth;
if(nMaxDepth<0 || m_nMaxDepth>getMaxDepth())
@@ -131,14 +168,14 @@ void TickIter::initIter( sal_Int32 /*nMinDepth*/, sal_Int32 nMaxDepth )
}
}
-TickIter::~TickIter()
+EquidistantTickIter::~EquidistantTickIter()
{
delete[] m_pnPositions;
delete[] m_pnPreParentCount;
delete[] m_pbIntervalFinished;
}
-sal_Int32 TickIter::getStartDepth() const
+sal_Int32 EquidistantTickIter::getStartDepth() const
{
//find the depth of the first visible tickmark:
//it is the depth of the smallest value
@@ -159,7 +196,7 @@ sal_Int32 TickIter::getStartDepth() const
return nReturnDepth;
}
-double* TickIter::firstValue()
+double* EquidistantTickIter::firstValue()
{
if( gotoFirst() )
{
@@ -169,14 +206,14 @@ double* TickIter::firstValue()
return NULL;
}
-TickInfo* TickIter::firstInfo()
+TickInfo* EquidistantTickIter::firstInfo()
{
if( m_pInfoTicks && gotoFirst() )
return &(*m_pInfoTicks)[m_nCurrentDepth][m_pnPositions[m_nCurrentDepth]];
return NULL;
}
-sal_Int32 TickIter::getIntervalCount( sal_Int32 nDepth )
+sal_Int32 EquidistantTickIter::getIntervalCount( sal_Int32 nDepth )
{
if(nDepth>m_rIncrement.SubIncrements.getLength() || nDepth<0)
return 0;
@@ -187,7 +224,7 @@ sal_Int32 TickIter::getIntervalCount( sal_Int32 nDepth )
return m_rIncrement.SubIncrements[nDepth-1].IntervalCount;
}
-bool TickIter::isAtLastPartTick()
+bool EquidistantTickIter::isAtLastPartTick()
{
if(!m_nCurrentDepth)
return false;
@@ -206,7 +243,7 @@ bool TickIter::isAtLastPartTick()
return bRet;
}
-bool TickIter::gotoFirst()
+bool EquidistantTickIter::gotoFirst()
{
if( m_nMaxDepth<0 )
return false;
@@ -222,7 +259,7 @@ bool TickIter::gotoFirst()
return true;
}
-bool TickIter::gotoNext()
+bool EquidistantTickIter::gotoNext()
{
if( m_nCurrentPos < 0 )
return false;
@@ -253,7 +290,7 @@ bool TickIter::gotoNext()
return true;
}
-bool TickIter::gotoIndex( sal_Int32 nTickIndex )
+bool EquidistantTickIter::gotoIndex( sal_Int32 nTickIndex )
{
if( nTickIndex < 0 )
return false;
@@ -271,16 +308,16 @@ bool TickIter::gotoIndex( sal_Int32 nTickIndex )
return true;
}
-sal_Int32 TickIter::getCurrentIndex() const
+sal_Int32 EquidistantTickIter::getCurrentIndex() const
{
return m_nCurrentPos;
}
-sal_Int32 TickIter::getMaxIndex() const
+sal_Int32 EquidistantTickIter::getMaxIndex() const
{
return m_nTickCount-1;
}
-double* TickIter::nextValue()
+double* EquidistantTickIter::nextValue()
{
if( gotoNext() )
{
@@ -290,7 +327,7 @@ double* TickIter::nextValue()
return NULL;
}
-TickInfo* TickIter::nextInfo()
+TickInfo* EquidistantTickIter::nextInfo()
{
if( m_pInfoTicks && gotoNext() &&
static_cast< sal_Int32 >(
@@ -649,7 +686,7 @@ void TickmarkHelper::getAllTicksShifted( ::std::vector< ::std::vector< TickInfo
void TickmarkHelper::addSubTicks( sal_Int32 nDepth, uno::Sequence< uno::Sequence< double > >& rParentTicks ) const
{
- TickIter aIter( rParentTicks, m_rIncrement, 0, nDepth-1 );
+ EquidistantTickIter aIter( rParentTicks, m_rIncrement, 0, nDepth-1 );
double* pfNextParentTick = aIter.firstValue();
if(!pfNextParentTick)
return;
@@ -756,11 +793,7 @@ sal_Int32 TickmarkHelper_2D::getTickScreenDistance( TickIter& rIter )
if(!pSecondTickInfo || !pFirstTickInfo)
return -1;
- B2DVector aDistance = pSecondTickInfo->aTickScreenPosition-pFirstTickInfo->aTickScreenPosition;
- sal_Int32 nRet = static_cast<sal_Int32>(aDistance.getLength());
- if(nRet<0)
- nRet *= -1;
- return nRet;
+ return pFirstTickInfo->getScreenDistanceBetweenTicks( *pSecondTickInfo );
}
B2DVector TickmarkHelper_2D::getTickScreenPosition2D( double fScaledLogicTickValue ) const
@@ -800,7 +833,7 @@ void TickmarkHelper_2D::addPointSequenceForTickLine( drawing::PointSequenceSeque
rPoints[nSequenceIndex][1].Y = static_cast<sal_Int32>(aEnd.getY());
}
-B2DVector TickmarkHelper_2D::getDistanceAxisTickToText( const AxisProperties& rAxisProperties ) const
+B2DVector TickmarkHelper_2D::getDistanceAxisTickToText( const AxisProperties& rAxisProperties, bool bIncludeFarAwayDistanceIfSo, bool bIncludeSpaceBetweenTickAndText ) const
{
bool bFarAwayLabels = false;
if( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START == rAxisProperties.m_eLabelPos
@@ -846,8 +879,9 @@ B2DVector TickmarkHelper_2D::getDistanceAxisTickToText( const AxisProperties& rA
if( rAxisProperties.m_fInnerDirectionSign != rAxisProperties.m_fLabelDirectionSign )
aOrthoLabelDirection*=-1.0;
aOrthoLabelDirection.normalize();
- aLabelDirection += aOrthoLabelDirection*AXIS2D_TICKLABELSPACING;
- if( bFarAwayLabels )
+ if( bIncludeSpaceBetweenTickAndText )
+ aLabelDirection += aOrthoLabelDirection*AXIS2D_TICKLABELSPACING;
+ if( bFarAwayLabels && bIncludeFarAwayDistanceIfSo )
aLabelDirection += m_aAxisLineToLabelLineShift;
return aLabelDirection;
}
@@ -879,27 +913,6 @@ void TickmarkHelper_2D::updateScreenValues( ::std::vector< ::std::vector< TickIn
}
}
-//'hide' tickmarks with identical screen values in aAllTickInfos
-void TickmarkHelper_2D::hideIdenticalScreenValues(
- ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
-{
- TickIter aIter( rAllTickInfos, m_rIncrement );
-
- TickInfo* pPreviousTickInfo = aIter.firstInfo();
- if(!pPreviousTickInfo)
- return;
- pPreviousTickInfo->bPaintIt = true;
- for( TickInfo* pTickInfo = aIter.nextInfo(); pTickInfo; pTickInfo = aIter.nextInfo())
- {
- pTickInfo->bPaintIt =
- ( static_cast<sal_Int32>(pTickInfo->aTickScreenPosition.getX())
- != static_cast<sal_Int32>(pPreviousTickInfo->aTickScreenPosition.getX()) )
- ||
- ( static_cast<sal_Int32>(pTickInfo->aTickScreenPosition.getY())
- != static_cast<sal_Int32>(pPreviousTickInfo->aTickScreenPosition.getY()) );
- pPreviousTickInfo = pTickInfo;
- }
-}
//-----------------------------------------------------------------------------
// ___TickmarkHelper_3D___
//-----------------------------------------------------------------------------
diff --git a/chart2/source/view/axes/TickmarkHelper.hxx b/chart2/source/view/axes/TickmarkHelper.hxx
index a5749a074582..b28f98ce1b28 100644
--- a/chart2/source/view/axes/TickmarkHelper.hxx
+++ b/chart2/source/view/axes/TickmarkHelper.hxx
@@ -62,23 +62,48 @@ struct TickInfo
::com::sun::star::uno::Reference<
::com::sun::star::drawing::XShape > xTextShape;
+ rtl::OUString aText;//used only for complex categories so far
+ sal_Int32 nFactorForLimitedTextWidth;//categories in higher levels of complex categories can have more place than a single simple category
+
//methods:
TickInfo();
void updateUnscaledValue( const ::com::sun::star::uno::Reference<
::com::sun::star::chart2::XScaling >& xInverseScaling );
-};
+ sal_Int32 getScreenDistanceBetweenTicks( const TickInfo& rOherTickInfo ) const;
+};
class TickIter
{
public:
- TickIter( const ::com::sun::star::uno::Sequence<
+ virtual ~TickIter(){};
+ virtual TickInfo* firstInfo()=0;
+ virtual TickInfo* nextInfo()=0;
+};
+
+class PureTickIter : public TickIter
+{
+public:
+ PureTickIter( ::std::vector< TickInfo >& rTickInfoVector );
+ virtual ~PureTickIter();
+ virtual TickInfo* firstInfo();
+ virtual TickInfo* nextInfo();
+
+private:
+ ::std::vector< TickInfo >& m_rTickVector;
+ ::std::vector< TickInfo >::iterator m_aTickIter;
+};
+
+class EquidistantTickIter : public TickIter
+{
+public:
+ EquidistantTickIter( const ::com::sun::star::uno::Sequence<
::com::sun::star::uno::Sequence< double > >& rTicks
, const ::com::sun::star::chart2::ExplicitIncrementData& rIncrement
, sal_Int32 nMinDepth=0, sal_Int32 nMaxDepth=-1 );
- TickIter( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
+ EquidistantTickIter( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
, const ::com::sun::star::chart2::ExplicitIncrementData& rIncrement
, sal_Int32 nMinDepth=0, sal_Int32 nMaxDepth=-1 );
- virtual ~TickIter();
+ virtual ~EquidistantTickIter();
virtual double* firstValue();
virtual double* nextValue();
@@ -174,7 +199,6 @@ protected: //methods
bool isWithinOuterBorder( double fScaledValue ) const; //all within the outer major tick marks
virtual void updateScreenValues( ::std::vector< ::std::vector< TickInfo > >& /*rAllTickInfos*/ ) const {}
- virtual void hideIdenticalScreenValues( ::std::vector< ::std::vector< TickInfo > >& /*rAllTickInfos*/ ) const {}
protected: //member
::com::sun::star::chart2::ExplicitScaleData m_rScale;
@@ -214,10 +238,11 @@ public:
, sal_Int32 nSequenceIndex
, double fScaledLogicTickValue, double fInnerDirectionSign
, const TickmarkProperties& rTickmarkProperties, bool bPlaceAtLabels ) const;
- ::basegfx::B2DVector getDistanceAxisTickToText( const AxisProperties& rAxisProperties ) const;
+ ::basegfx::B2DVector getDistanceAxisTickToText( const AxisProperties& rAxisProperties
+ , bool bIncludeFarAwayDistanceIfSo = false
+ , bool bIncludeSpaceBetweenTickAndText = true ) const;
virtual void updateScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const;
- virtual void hideIdenticalScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const;
bool isHorizontalAxis() const;
bool isVerticalAxis() const;
diff --git a/chart2/source/view/axes/VAxisBase.cxx b/chart2/source/view/axes/VAxisBase.cxx
index be24262e8801..530da86dab8f 100644
--- a/chart2/source/view/axes/VAxisBase.cxx
+++ b/chart2/source/view/axes/VAxisBase.cxx
@@ -98,13 +98,15 @@ void SAL_CALL VAxisBase::initAxisLabelProperties( const ::com::sun::star::awt::S
else if( AxisType::CATEGORY==m_aAxisProperties.m_nAxisType )
{
if( m_aAxisProperties.m_pExplicitCategoriesProvider )
- m_aTextLabels = m_aAxisProperties.m_pExplicitCategoriesProvider->getTextualData();
+ m_aTextLabels = m_aAxisProperties.m_pExplicitCategoriesProvider->getSimpleCategories();
m_bUseTextLabels = true;
}
m_aAxisLabelProperties.nNumberFormatKey = m_aAxisProperties.m_nNumberFormatKey;
m_aAxisLabelProperties.init(m_aAxisProperties.m_xAxisModel);
+ if( m_aAxisProperties.m_bComplexCategories && AxisType::CATEGORY == m_aAxisProperties.m_nAxisType )
+ m_aAxisLabelProperties.eStaggering = SIDE_BY_SIDE;
}
void VAxisBase::recordMaximumTextSize( const Reference< drawing::XShape >& xShape, double fRotationAngleDegree )
@@ -161,6 +163,12 @@ void SAL_CALL VAxisBase::setExplicitScaleAndIncrement(
m_aIncrement = rIncrement;
}
+void VAxisBase::createAllTickInfos( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
+{
+ std::auto_ptr< TickmarkHelper > apTickmarkHelper( this->createTickmarkHelper() );
+ apTickmarkHelper->getAllTicks( rAllTickInfos );
+}
+
bool VAxisBase::prepareShapeCreation()
{
//returns true if all is ready for further shape creation and any shapes need to be created
@@ -171,14 +179,9 @@ bool VAxisBase::prepareShapeCreation()
{
//-----------------------------------------
//create all scaled tickmark values
- if( m_xTextTarget.is() )
- {
- TickIter aRemoveIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
- removeTextShapesFromTicks( aRemoveIter, m_xTextTarget );
- }
+ removeTextShapesFromTicks();
- std::auto_ptr< TickmarkHelper > apTickmarkHelper( this->createTickmarkHelper() );
- apTickmarkHelper->getAllTicks( m_aAllTickInfos );
+ createAllTickInfos(m_aAllTickInfos);
m_bReCreateAllTickInfos = false;
}
@@ -212,15 +215,25 @@ sal_Int32 VAxisBase::getIndexOfLongestLabel( const uno::Sequence< rtl::OUString
return nRet;
}
-void VAxisBase::removeTextShapesFromTicks( TickIter& rIter, const Reference< drawing::XShapes >& xTarget )
+void VAxisBase::removeTextShapesFromTicks()
{
- for( TickInfo* pTickInfo = rIter.firstInfo()
- ; pTickInfo; pTickInfo = rIter.nextInfo() )
+ if( m_xTextTarget.is() )
{
- if(pTickInfo->xTextShape.is())
+ ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = m_aAllTickInfos.begin();
+ const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = m_aAllTickInfos.end();
+ for( ; aDepthIter != aDepthEnd; aDepthIter++ )
{
- xTarget->remove(pTickInfo->xTextShape);
- pTickInfo->xTextShape = NULL;
+ ::std::vector< TickInfo >::iterator aTickIter = (*aDepthIter).begin();
+ const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end();
+ for( ; aTickIter != aTickEnd; aTickIter++ )
+ {
+ TickInfo& rTickInfo = (*aTickIter);
+ if(rTickInfo.xTextShape.is())
+ {
+ m_xTextTarget->remove(rTickInfo.xTextShape);
+ rTickInfo.xTextShape = NULL;
+ }
+ }
}
}
}
diff --git a/chart2/source/view/axes/VAxisBase.hxx b/chart2/source/view/axes/VAxisBase.hxx
index ab826caca2ff..6f8000af50de 100644
--- a/chart2/source/view/axes/VAxisBase.hxx
+++ b/chart2/source/view/axes/VAxisBase.hxx
@@ -70,6 +70,7 @@ public:
throw (::com::sun::star::uno::RuntimeException);
virtual sal_Int32 estimateMaximumAutoMainIncrementCount();
+ virtual void createAllTickInfos( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos );
void setExrtaLinePositionAtOtherAxis( const double& fCrossingAt );
@@ -77,7 +78,7 @@ public:
//-------------------------------------------------------------------------
protected: //methods
sal_Int32 getIndexOfLongestLabel( const ::com::sun::star::uno::Sequence< rtl::OUString >& rLabels );
- void removeTextShapesFromTicks( TickIter& rIter, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget );
+ void removeTextShapesFromTicks();
void updateUnscaledValuesAtTicks( TickIter& rIter );
virtual bool prepareShapeCreation();
diff --git a/chart2/source/view/axes/VAxisProperties.cxx b/chart2/source/view/axes/VAxisProperties.cxx
index eea2b2eb47f2..35fd0874399f 100644
--- a/chart2/source/view/axes/VAxisProperties.cxx
+++ b/chart2/source/view/axes/VAxisProperties.cxx
@@ -147,6 +147,18 @@ TickmarkProperties AxisProperties::makeTickmarkProperties(
return aTickmarkProperties;
}
+TickmarkProperties AxisProperties::makeTickmarkPropertiesForComplexCategories(
+ sal_Int32 nTickLength, sal_Int32 nTickStartDistanceToAxis, sal_Int32 nTextLevel ) const
+{
+ sal_Int32 nTickmarkStyle = (m_fLabelDirectionSign==m_fInnerDirectionSign) ? 2/*outside*/ : 1/*inside*/;
+
+ TickmarkProperties aTickmarkProperties;
+ aTickmarkProperties.Length = nTickLength;// + nTextLevel*( lcl_calcTickLengthForDepth(0,nTickmarkStyle) );
+ aTickmarkProperties.RelativePos = static_cast<sal_Int32>(lcl_getTickOffset(aTickmarkProperties.Length+nTickStartDistanceToAxis,nTickmarkStyle));
+ aTickmarkProperties.aLineProperties = this->makeLinePropertiesForDepth( 0 );
+ return aTickmarkProperties;
+}
+
//static
TickmarkProperties AxisProperties::getBiggestTickmarkProperties()
{
@@ -176,7 +188,6 @@ AxisProperties::AxisProperties( const uno::Reference< XAxis >& xAxisModel
, m_bAxisBetweenCategories(false)
, m_fLabelDirectionSign(1.0)
, m_fInnerDirectionSign(1.0)
- , m_bLabelsOutside(true)
, m_aLabelAlignment(LABEL_ALIGN_RIGHT_TOP)
, m_bDisplayLabels( true )
, m_nNumberFormatKey(0)
@@ -186,9 +197,9 @@ AxisProperties::AxisProperties( const uno::Reference< XAxis >& xAxisModel
, m_aLineProperties()
//for category axes
, m_nAxisType(AxisType::REALNUMBER)
+ , m_bComplexCategories(false)
, m_pExplicitCategoriesProvider(pExplicitCategoriesProvider)
, m_xAxisTextProvider(0)
- , m_bTickmarksAtIndicatedValue(false)
{
}
@@ -207,7 +218,6 @@ AxisProperties::AxisProperties( const AxisProperties& rAxisProperties )
, m_bAxisBetweenCategories( rAxisProperties.m_bAxisBetweenCategories )
, m_fLabelDirectionSign( rAxisProperties.m_fLabelDirectionSign )
, m_fInnerDirectionSign( rAxisProperties.m_fInnerDirectionSign )
- , m_bLabelsOutside( rAxisProperties.m_bLabelsOutside )
, m_aLabelAlignment( rAxisProperties.m_aLabelAlignment )
, m_bDisplayLabels( rAxisProperties.m_bDisplayLabels )
, m_nNumberFormatKey( rAxisProperties.m_nNumberFormatKey )
@@ -217,9 +227,9 @@ AxisProperties::AxisProperties( const AxisProperties& rAxisProperties )
, m_aLineProperties( rAxisProperties.m_aLineProperties )
//for category axes
, m_nAxisType( rAxisProperties.m_nAxisType )
+ , m_bComplexCategories( rAxisProperties.m_bComplexCategories )
, m_pExplicitCategoriesProvider( rAxisProperties.m_pExplicitCategoriesProvider )
, m_xAxisTextProvider( rAxisProperties.m_xAxisTextProvider )
- , m_bTickmarksAtIndicatedValue( rAxisProperties.m_bTickmarksAtIndicatedValue )
{
if( rAxisProperties.m_pfMainLinePositionAtOtherAxis )
m_pfMainLinePositionAtOtherAxis = new double(*rAxisProperties.m_pfMainLinePositionAtOtherAxis);
diff --git a/chart2/source/view/axes/VAxisProperties.hxx b/chart2/source/view/axes/VAxisProperties.hxx
index 56ef075bfdb2..c307bf5a3af7 100644
--- a/chart2/source/view/axes/VAxisProperties.hxx
+++ b/chart2/source/view/axes/VAxisProperties.hxx
@@ -88,7 +88,7 @@ struct AxisLabelProperties
double fRotationAngleDegree;
sal_Int32 nRhythm; //show only each nth label with n==nRhythm
- bool bRhythmIsFix; //states wether the given rythm is fix or may be changed
+ bool bRhythmIsFix; //states wether the given rhythm is fix or may be changed
//methods:
void init( const ::com::sun::star::uno::Reference<
@@ -120,7 +120,6 @@ struct AxisProperties
double m_fLabelDirectionSign;
//this direction is used to indicate in which direction inner tickmarks are to be drawn
double m_fInnerDirectionSign;
- bool m_bLabelsOutside;
LabelAlignment m_aLabelAlignment;
sal_Bool m_bDisplayLabels;
@@ -137,13 +136,12 @@ struct AxisProperties
VLineProperties m_aLineProperties;
//for category axes ->
- sal_Int32 m_nAxisType;//REALNUMBER, CATEGORY etc. type ::com::sun::star::chart2::AxisType
+ sal_Int32 m_nAxisType;//REALNUMBER, CATEGORY etc. type ::com::sun::star::chart2::AxisType
+ bool m_bComplexCategories;
ExplicitCategoriesProvider* m_pExplicitCategoriesProvider;/*no ownership here*/
::com::sun::star::uno::Reference<
::com::sun::star::chart2::data::XTextualDataSequence >
m_xAxisTextProvider; //for categries or series names
- //position of main tickmarks in respect to the indicated value: at value or between neighboured indicated values
- bool m_bTickmarksAtIndicatedValue;
//<- category axes
//methods:
@@ -157,6 +155,7 @@ struct AxisProperties
void initAxisPositioning( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xAxisProp );
static TickmarkProperties getBiggestTickmarkProperties();
+ TickmarkProperties makeTickmarkPropertiesForComplexCategories( sal_Int32 nTickLength, sal_Int32 nTickStartDistanceToAxis, sal_Int32 nTextLevel ) const;
private:
AxisProperties();
diff --git a/chart2/source/view/axes/VCartesianAxis.cxx b/chart2/source/view/axes/VCartesianAxis.cxx
index 0f18029254ef..430945a0fd96 100644
--- a/chart2/source/view/axes/VCartesianAxis.cxx
+++ b/chart2/source/view/axes/VCartesianAxis.cxx
@@ -121,19 +121,19 @@ Reference< drawing::XShape > createSingleLabel(
bool lcl_doesShapeOverlapWithTickmark( const Reference< drawing::XShape >& xShape
, double fRotationAngleDegree
, const basegfx::B2DVector& rTickScreenPosition
- , TickmarkHelper_2D* pTickmarkHelper )
+ , bool bIsHorizontalAxis, bool bIsVerticalAxis )
{
if(!xShape.is())
return false;
::basegfx::B2IRectangle aShapeRect = BaseGFXHelper::makeRectangle(xShape->getPosition(),ShapeFactory::getSizeAfterRotation( xShape, fRotationAngleDegree ));
- if( pTickmarkHelper->isVerticalAxis() )
+ if( bIsVerticalAxis )
{
return ( (rTickScreenPosition.getY() >= aShapeRect.getMinY())
&& (rTickScreenPosition.getY() <= aShapeRect.getMaxY()) );
}
- if( pTickmarkHelper->isHorizontalAxis() )
+ if( bIsHorizontalAxis )
{
return ( (rTickScreenPosition.getX() >= aShapeRect.getMinX())
&& (rTickScreenPosition.getX() <= aShapeRect.getMaxX()) );
@@ -157,7 +157,7 @@ bool doesOverlap( const Reference< drawing::XShape >& xShape1
return aRect1.overlaps(aRect2);
}
-void removeShapesAtWrongRythm( TickIter& rIter
+void removeShapesAtWrongRhythm( TickIter& rIter
, sal_Int32 nCorrectRhythm
, sal_Int32 nMaxTickToCheck
, const Reference< drawing::XShapes >& xTarget )
@@ -167,7 +167,7 @@ void removeShapesAtWrongRythm( TickIter& rIter
; pTickInfo && nTick <= nMaxTickToCheck
; pTickInfo = rIter.nextInfo(), nTick++ )
{
- //remove labels which does not fit into the rythm
+ //remove labels which does not fit into the rhythm
if( nTick%nCorrectRhythm != 0)
{
if(pTickInfo->xTextShape.is())
@@ -179,7 +179,7 @@ void removeShapesAtWrongRythm( TickIter& rIter
}
}
-class LabelIterator : private TickIter
+class EquidistantLabelIterator : public EquidistantTickIter
{
//this Iterator iterates over existing text labels
@@ -193,7 +193,7 @@ class LabelIterator : private TickIter
//we iterate through all labels
public:
- LabelIterator( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
+ EquidistantLabelIterator( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
, const ::com::sun::star::chart2::ExplicitIncrementData& rIncrement
, const AxisLabelStaggering eAxisLabelStaggering
, bool bInnerLine
@@ -203,29 +203,29 @@ public:
virtual TickInfo* nextInfo();
private: //methods
- LabelIterator();
+ EquidistantLabelIterator();
private: //member
const AxisLabelStaggering m_eAxisLabelStaggering;
bool m_bInnerLine;
};
-LabelIterator::LabelIterator( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
+EquidistantLabelIterator::EquidistantLabelIterator( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
, const ::com::sun::star::chart2::ExplicitIncrementData& rIncrement
, const AxisLabelStaggering eAxisLabelStaggering
, bool bInnerLine
, sal_Int32 nMinDepth, sal_Int32 nMaxDepth )
- : TickIter( rTickInfos, rIncrement, nMinDepth, nMaxDepth )
+ : EquidistantTickIter( rTickInfos, rIncrement, nMinDepth, nMaxDepth )
, m_eAxisLabelStaggering(eAxisLabelStaggering)
, m_bInnerLine(bInnerLine)
{
}
-TickInfo* LabelIterator::firstInfo()
+TickInfo* EquidistantLabelIterator::firstInfo()
{
- TickInfo* pTickInfo = TickIter::firstInfo();
+ TickInfo* pTickInfo = EquidistantTickIter::firstInfo();
while( pTickInfo && !pTickInfo->xTextShape.is() )
- pTickInfo = TickIter::nextInfo();
+ pTickInfo = EquidistantTickIter::nextInfo();
if(!pTickInfo)
return NULL;
if( (STAGGER_EVEN==m_eAxisLabelStaggering && m_bInnerLine)
@@ -235,7 +235,7 @@ TickInfo* LabelIterator::firstInfo()
{
//skip first label
do
- pTickInfo = TickIter::nextInfo();
+ pTickInfo = EquidistantTickIter::nextInfo();
while( pTickInfo && !pTickInfo->xTextShape.is() );
}
if(!pTickInfo)
@@ -243,12 +243,12 @@ TickInfo* LabelIterator::firstInfo()
return pTickInfo;
}
-TickInfo* LabelIterator::nextInfo()
+TickInfo* EquidistantLabelIterator::nextInfo()
{
TickInfo* pTickInfo = NULL;
//get next label
do
- pTickInfo = TickIter::nextInfo();
+ pTickInfo = EquidistantTickIter::nextInfo();
while( pTickInfo && !pTickInfo->xTextShape.is() );
if( STAGGER_EVEN==m_eAxisLabelStaggering
@@ -256,16 +256,16 @@ TickInfo* LabelIterator::nextInfo()
{
//skip one label
do
- pTickInfo = TickIter::nextInfo();
+ pTickInfo = EquidistantTickIter::nextInfo();
while( pTickInfo && !pTickInfo->xTextShape.is() );
}
return pTickInfo;
}
-B2DVector lcl_getStaggerDistance( LabelIterator& rIter, const B2DVector& rDistanceTickToText )
+B2DVector lcl_getLabelsDistance( TickIter& rIter, const B2DVector& rDistanceTickToText )
{
- //calculates the height or width of the first line of labels
- //thus the second line of labels needs to be shifted for that distance
+ //calculates the height or width of a line of labels
+ //thus a following line of labels can be shifted for that distance
B2DVector aRet(0,0);
@@ -283,13 +283,14 @@ B2DVector lcl_getStaggerDistance( LabelIterator& rIter, const B2DVector& rDistan
; pTickInfo = rIter.nextInfo() )
{
xShape2DText = pTickInfo->xTextShape;
- DBG_ASSERT(xShape2DText.is(),"LabelIterator does not work correctly");
-
- awt::Size aSize = xShape2DText->getSize();
- if(fabs(aStaggerDirection.getX())>fabs(aStaggerDirection.getY()))
- nDistance = ::std::max(nDistance,aSize.Width);
- else
- nDistance = ::std::max(nDistance,aSize.Height);
+ if( xShape2DText.is() )
+ {
+ awt::Size aSize = xShape2DText->getSize();
+ if(fabs(aStaggerDirection.getX())>fabs(aStaggerDirection.getY()))
+ nDistance = ::std::max(nDistance,aSize.Width);
+ else
+ nDistance = ::std::max(nDistance,aSize.Height);
+ }
}
aRet = aStaggerDirection*nDistance;
@@ -301,7 +302,7 @@ B2DVector lcl_getStaggerDistance( LabelIterator& rIter, const B2DVector& rDistan
return aRet;
}
-void lcl_correctPositionForStaggering( LabelIterator& rIter, const B2DVector& rStaggerDistance )
+void lcl_shiftLables( TickIter& rIter, const B2DVector& rStaggerDistance )
{
if(rStaggerDistance.getLength()==0.0)
return;
@@ -311,23 +312,24 @@ void lcl_correctPositionForStaggering( LabelIterator& rIter, const B2DVector& rS
; pTickInfo = rIter.nextInfo() )
{
xShape2DText = pTickInfo->xTextShape;
- DBG_ASSERT(xShape2DText.is(),"LabelIterator does not work correctly");
-
- awt::Point aPos = xShape2DText->getPosition();
- aPos.X += static_cast<sal_Int32>(rStaggerDistance.getX());
- aPos.Y += static_cast<sal_Int32>(rStaggerDistance.getY());
- xShape2DText->setPosition( aPos );
+ if( xShape2DText.is() )
+ {
+ awt::Point aPos = xShape2DText->getPosition();
+ aPos.X += static_cast<sal_Int32>(rStaggerDistance.getX());
+ aPos.Y += static_cast<sal_Int32>(rStaggerDistance.getY());
+ xShape2DText->setPosition( aPos );
+ }
}
}
-class MaxLabelTickIter : public TickIter
+class MaxLabelEquidistantTickIter : public EquidistantTickIter
{
//iterate over first two and last two labels and the longest label
public:
- MaxLabelTickIter( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
+ MaxLabelEquidistantTickIter( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
, const ::com::sun::star::chart2::ExplicitIncrementData& rIncrement
, sal_Int32 nLongestLabelIndex );
- virtual ~MaxLabelTickIter();
+ virtual ~MaxLabelEquidistantTickIter();
virtual TickInfo* nextInfo();
@@ -335,10 +337,10 @@ private:
sal_Int32 m_nLongestLabelIndex;
};
-MaxLabelTickIter::MaxLabelTickIter( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
+MaxLabelEquidistantTickIter::MaxLabelEquidistantTickIter( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
, const ::com::sun::star::chart2::ExplicitIncrementData& rIncrement
, sal_Int32 nLongestLabelIndex )
- : TickIter( rTickInfos, rIncrement, 0//nMinDepth
+ : EquidistantTickIter( rTickInfos, rIncrement, 0//nMinDepth
, 0//nMaxDepth
)
, m_nLongestLabelIndex( nLongestLabelIndex )
@@ -356,11 +358,11 @@ MaxLabelTickIter::MaxLabelTickIter( ::std::vector< ::std::vector< TickInfo > >&
if( m_nLongestLabelIndex+1==nMaxIndex )
m_nLongestLabelIndex = 0;
}
-MaxLabelTickIter::~MaxLabelTickIter()
+MaxLabelEquidistantTickIter::~MaxLabelEquidistantTickIter()
{
}
-TickInfo* MaxLabelTickIter::nextInfo()
+TickInfo* MaxLabelEquidistantTickIter::nextInfo()
{
sal_Int32 nCurrentPos = getCurrentIndex();
sal_Int32 nMaxIndex = getMaxIndex();
@@ -377,11 +379,11 @@ TickInfo* MaxLabelTickIter::nextInfo()
}
}
- return TickIter::nextInfo();
+ return EquidistantTickIter::nextInfo();
}
bool VCartesianAxis::isBreakOfLabelsAllowed( const AxisLabelProperties& rAxisLabelProperties
- , TickmarkHelper_2D* pTickmarkHelper )
+ , bool bIsHorizontalAxis )
{
if( m_aTextLabels.getLength() > 100 )
return false;
@@ -395,13 +397,11 @@ bool VCartesianAxis::isBreakOfLabelsAllowed( const AxisLabelProperties& rAxisLab
if( !::rtl::math::approxEqual( rAxisLabelProperties.fRotationAngleDegree, 0.0 ) )
return false;
//break only for horizontal axis
- if( pTickmarkHelper )
- return pTickmarkHelper->isHorizontalAxis();
- return false;
+ return bIsHorizontalAxis;
}
bool VCartesianAxis::isAutoStaggeringOfLabelsAllowed( const AxisLabelProperties& rAxisLabelProperties
- , TickmarkHelper_2D* pTickmarkHelper )
+ , bool bIsHorizontalAxis, bool bIsVerticalAxis )
{
if( rAxisLabelProperties.eStaggering != STAGGER_AUTO )
return false;
@@ -413,28 +413,163 @@ bool VCartesianAxis::isAutoStaggeringOfLabelsAllowed( const AxisLabelProperties&
return false;
//automatic staggering only for horizontal axis with horizontal text
//or vertical axis with vertical text
- if( pTickmarkHelper )
+ if( bIsHorizontalAxis )
+ return !rAxisLabelProperties.bStackCharacters;
+ if( bIsVerticalAxis )
+ return rAxisLabelProperties.bStackCharacters;
+ return false;
+}
+
+struct ComplexCategoryPlacement
+{
+ rtl::OUString Text;
+ sal_Int32 Count;
+ double TickValue;
+
+ ComplexCategoryPlacement( const rtl::OUString& rText, sal_Int32 nCount, double fTickValue )
+ : Text(rText), Count(nCount), TickValue(fTickValue)
+ {}
+};
+
+void VCartesianAxis::createAllTickInfosFromComplexCategories( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos, bool bShiftedPosition )
+{
+ //no minor tickmarks will be generated!
+ //order is: inner labels first , outer labels last (that is different to all other TickIter cases)
+ if(!bShiftedPosition)
{
- if( pTickmarkHelper->isHorizontalAxis() )
- return !rAxisLabelProperties.bStackCharacters;
- if( pTickmarkHelper->isVerticalAxis() )
- return rAxisLabelProperties.bStackCharacters;
+ rAllTickInfos.clear();
+ sal_Int32 nLevel=0;
+ sal_Int32 nLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
+ for( ; nLevel<nLevelCount; nLevel++ )
+ {
+ ::std::vector< TickInfo > aTickInfoVector;
+ std::vector< ComplexCategory > aComplexCategories( m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoriesByLevel( nLevel ) );
+ sal_Int32 nCatIndex = 0;
+ std::vector< ComplexCategory >::const_iterator aIt(aComplexCategories.begin());
+ std::vector< ComplexCategory >::const_iterator aEnd(aComplexCategories.end());
+ for(;aIt!=aEnd;++aIt)
+ {
+ TickInfo aTickInfo;
+ ComplexCategory aCat(*aIt);
+ sal_Int32 nCount = aCat.Count;
+ if( nCatIndex + 0.5 + nCount >= m_aScale.Maximum )
+ {
+ nCount = m_aScale.Maximum - 0.5 - nCatIndex;
+ if( nCount <= 0 )
+ nCount = 1;
+ }
+ aTickInfo.fScaledTickValue = nCatIndex + 0.5 + nCount/2.0;
+ aTickInfo.nFactorForLimitedTextWidth = nCount;
+ aTickInfo.aText = aCat.Text;
+ aTickInfoVector.push_back(aTickInfo);
+ nCatIndex += nCount;
+ if( nCatIndex + 0.5 >= m_aScale.Maximum )
+ break;
+ }
+ rAllTickInfos.push_back(aTickInfoVector);
+ }
+ }
+ else //bShiftedPosition==true
+ {
+ rAllTickInfos.clear();
+ sal_Int32 nLevel=0;
+ sal_Int32 nLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
+ for( ; nLevel<nLevelCount; nLevel++ )
+ {
+ ::std::vector< TickInfo > aTickInfoVector;
+ std::vector< ComplexCategory > aComplexCategories( m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoriesByLevel( nLevel ) );
+ sal_Int32 nCatIndex = 0;
+ std::vector< ComplexCategory >::const_iterator aIt(aComplexCategories.begin());
+ std::vector< ComplexCategory >::const_iterator aEnd(aComplexCategories.end());
+ for(;aIt!=aEnd;++aIt)
+ {
+ TickInfo aTickInfo;
+ ComplexCategory aCat(*aIt);
+ aTickInfo.fScaledTickValue = nCatIndex + 0.5;
+ aTickInfoVector.push_back(aTickInfo);
+ nCatIndex += aCat.Count;
+ if( nCatIndex + 0.5 > m_aScale.Maximum )
+ break;
+ }
+ //fill up with single ticks until maximum scale
+ while( nCatIndex + 0.5 < m_aScale.Maximum )
+ {
+ TickInfo aTickInfo;
+ aTickInfo.fScaledTickValue = nCatIndex + 0.5;
+ aTickInfoVector.push_back(aTickInfo);
+ nCatIndex ++;
+ if( nLevel>0 )
+ break;
+ }
+ //add an additional tick at the end
+ {
+ TickInfo aTickInfo;
+ aTickInfo.fScaledTickValue = m_aScale.Maximum;
+ aTickInfoVector.push_back(aTickInfo);
+ }
+ rAllTickInfos.push_back(aTickInfoVector);
+ }
}
- return false;
+}
+
+void VCartesianAxis::createAllTickInfos( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
+{
+ if( m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels )
+ createAllTickInfosFromComplexCategories( rAllTickInfos, false );
+ else
+ VAxisBase::createAllTickInfos(rAllTickInfos);
+}
+
+::std::auto_ptr< TickIter > VCartesianAxis::createLabelTickIterator( sal_Int32 nTextLevel )
+{
+ if( m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels )
+ {
+ if( nTextLevel>=0 && nTextLevel < m_aAllTickInfos.size() )
+ return ::std::auto_ptr< TickIter >( new PureTickIter( m_aAllTickInfos[nTextLevel] ) );
+ }
+ else
+ {
+ if(nTextLevel==0)
+ return ::std::auto_ptr< TickIter >( new EquidistantTickIter( m_aAllTickInfos, m_aIncrement, 0, 0 ) );
+ }
+ return ::std::auto_ptr< TickIter >();
+}
+::std::auto_ptr< TickIter > VCartesianAxis::createMaximumLabelTickIterator( sal_Int32 nTextLevel )
+{
+ if( m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels )
+ {
+ return createLabelTickIterator( nTextLevel ); //mmmm maybe todo: create less than all texts here
+ }
+ else
+ {
+ if(nTextLevel==0)
+ {
+ sal_Int32 nLongestLabelIndex = m_bUseTextLabels ? this->getIndexOfLongestLabel( m_aTextLabels ) : 0;
+ return ::std::auto_ptr< TickIter >( new MaxLabelEquidistantTickIter( m_aAllTickInfos, m_aIncrement, nLongestLabelIndex ) );
+ }
+ }
+ return ::std::auto_ptr< TickIter >();
+}
+
+sal_Int32 VCartesianAxis::getTextLevelCount() const
+{
+ sal_Int32 nTextLevelCount = 1;
+ if( m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels )
+ nTextLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
+ return nTextLevelCount;
}
bool VCartesianAxis::createTextShapes(
const Reference< drawing::XShapes >& xTarget
, TickIter& rTickIter
, AxisLabelProperties& rAxisLabelProperties
- , TickmarkHelper_2D* pTickmarkHelper )
+ , TickmarkHelper_2D* pTickmarkHelper
+ , sal_Int32 nScreenDistanceBetweenTicks )
{
//returns true if the text shapes have been created succesfully
//otherwise false - in this case the AxisLabelProperties have changed
//and contain new instructions for the next try for text shape creation
- uno::Sequence< rtl::OUString >* pCategories = m_bUseTextLabels? &m_aTextLabels : 0;
-
Reference< XScaling > xInverseScaling( NULL );
if( m_aScale.Scaling.is() )
xInverseScaling = m_aScale.Scaling->getInverseScaling();
@@ -442,40 +577,44 @@ bool VCartesianAxis::createTextShapes(
FixedNumberFormatter aFixedNumberFormatter(
m_xNumberFormatsSupplier, rAxisLabelProperties.nNumberFormatKey );
- B2DVector aTextToTickDistance( pTickmarkHelper->getDistanceAxisTickToText( m_aAxisProperties ) );
-
- TickInfo* pPreviousVisibleTickInfo = NULL;
- TickInfo* pPREPreviousVisibleTickInfo = NULL;
- TickInfo* pLastVisibleNeighbourTickInfo = NULL;
+ const bool bIsHorizontalAxis = pTickmarkHelper->isHorizontalAxis();
+ const bool bIsVerticalAxis = pTickmarkHelper->isVerticalAxis();
bool bIsStaggered = rAxisLabelProperties.getIsStaggered();
- sal_Int32 nLimitedSpace = -1;
- if( isBreakOfLabelsAllowed( rAxisLabelProperties, pTickmarkHelper ) )
+ B2DVector aTextToTickDistance( pTickmarkHelper->getDistanceAxisTickToText( m_aAxisProperties, true ) );
+ sal_Int32 nLimitedSpaceForText = -1;
+ if( isBreakOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis ) )
{
- nLimitedSpace = TickmarkHelper_2D::getTickScreenDistance( rTickIter );
+ nLimitedSpaceForText = nScreenDistanceBetweenTicks;
if( bIsStaggered )
- nLimitedSpace *= 2;
+ nLimitedSpaceForText *= 2;
- if( nLimitedSpace > 0 )
+ if( nLimitedSpaceForText > 0 )
{ //reduce space for a small amount to have a visible distance between the labels:
- sal_Int32 nReduce = (nLimitedSpace*5)/100;
+ sal_Int32 nReduce = (nLimitedSpaceForText*5)/100;
if(!nReduce)
nReduce = 1;
- nLimitedSpace -= nReduce;
+ nLimitedSpaceForText -= nReduce;
}
- //maybe @todo in future:
- //if the labeled tickmarks are not equidistant [this is not considered to be a relevant case so far]
- //the limited space maybe needs to be calculated for each tickmark seperatly
- //or the staggering could be ignored in that case
}
+ std::vector< ComplexCategoryPlacement > aComplexCategoryPlacements;
+ uno::Sequence< rtl::OUString >* pCategories = 0;
+ if( m_bUseTextLabels && !m_aAxisProperties.m_bComplexCategories )
+ pCategories = &m_aTextLabels;
+
+ TickInfo* pPreviousVisibleTickInfo = NULL;
+ TickInfo* pPREPreviousVisibleTickInfo = NULL;
+ TickInfo* pLastVisibleNeighbourTickInfo = NULL;
+
//------------------------------------------------
//prepare properties for multipropertyset-interface of shape
tNameSequence aPropNames;
tAnySequence aPropValues;
+ bool bLimitedHeight = fabs(aTextToTickDistance.getX()) > fabs(aTextToTickDistance.getY());
Reference< beans::XPropertySet > xProps( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY );
PropertyMapper::getTextLabelMultiPropertyLists( xProps, aPropNames, aPropValues, false
- , nLimitedSpace, fabs(aTextToTickDistance.getX()) > fabs(aTextToTickDistance.getY()) );
+ , nLimitedSpaceForText, bLimitedHeight );
LabelPositionHelper::doDynamicFontResize( aPropValues, aPropNames, xProps
, m_aAxisLabelProperties.m_aFontReferenceSize );
LabelPositionHelper::changeTextAdjustment( aPropValues, aPropNames, m_aAxisProperties.m_aLabelAlignment );
@@ -484,6 +623,8 @@ bool VCartesianAxis::createTextShapes(
sal_Int32 nColor = Color( COL_AUTO ).GetColor();
if(pColorAny)
*pColorAny >>= nColor;
+
+ uno::Any* pLimitedSpaceAny = PropertyMapper::getValuePointerForLimitedSpace(aPropValues,aPropNames,bLimitedHeight);
//------------------------------------------------
sal_Int32 nTick = 0;
@@ -494,7 +635,7 @@ bool VCartesianAxis::createTextShapes(
pLastVisibleNeighbourTickInfo = bIsStaggered ?
pPREPreviousVisibleTickInfo : pPreviousVisibleTickInfo;
- //don't create labels which does not fit into the rythm
+ //don't create labels which does not fit into the rhythm
if( nTick%rAxisLabelProperties.nRhythm != 0)
continue;
@@ -508,10 +649,11 @@ bool VCartesianAxis::createTextShapes(
{
if( lcl_doesShapeOverlapWithTickmark( pLastVisibleNeighbourTickInfo->xTextShape
, rAxisLabelProperties.fRotationAngleDegree
- , pTickInfo->aTickScreenPosition, pTickmarkHelper ) )
+ , pTickInfo->aTickScreenPosition
+ , bIsHorizontalAxis, bIsVerticalAxis ) )
{
bool bOverlapAlsoAfterSwitchingOnAutoStaggering = true;
- if( !bIsStaggered && isAutoStaggeringOfLabelsAllowed( rAxisLabelProperties, pTickmarkHelper ) )
+ if( !bIsStaggered && isAutoStaggeringOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis ) )
{
bIsStaggered = true;
rAxisLabelProperties.eStaggering = STAGGER_EVEN;
@@ -519,7 +661,8 @@ bool VCartesianAxis::createTextShapes(
if( !pLastVisibleNeighbourTickInfo ||
!lcl_doesShapeOverlapWithTickmark( pLastVisibleNeighbourTickInfo->xTextShape
, rAxisLabelProperties.fRotationAngleDegree
- , pTickInfo->aTickScreenPosition, pTickmarkHelper ) )
+ , pTickInfo->aTickScreenPosition
+ , bIsHorizontalAxis, bIsVerticalAxis ) )
bOverlapAlsoAfterSwitchingOnAutoStaggering = false;
}
if( bOverlapAlsoAfterSwitchingOnAutoStaggering )
@@ -527,8 +670,7 @@ bool VCartesianAxis::createTextShapes(
if( rAxisLabelProperties.bRhythmIsFix )
continue;
rAxisLabelProperties.nRhythm++;
- TickIter aRemoveIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
- removeShapesAtWrongRythm( aRemoveIter, rAxisLabelProperties.nRhythm, nTick, xTarget );
+ removeShapesAtWrongRhythm( rTickIter, rAxisLabelProperties.nRhythm, nTick, xTarget );
return false;
}
}
@@ -546,11 +688,17 @@ bool VCartesianAxis::createTextShapes(
if( nIndex>=0 && nIndex<pCategories->getLength() )
aLabel = (*pCategories)[nIndex];
}
+ else if( m_aAxisProperties.m_bComplexCategories )
+ {
+ aLabel = pTickInfo->aText;
+ }
else
aLabel = aFixedNumberFormatter.getFormattedString( pTickInfo->fUnscaledTickValue, nExtraColor, bHasExtraColor );
if(pColorAny)
*pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor);
+ if(pLimitedSpaceAny)
+ *pLimitedSpaceAny = uno::makeAny(sal_Int32(nLimitedSpaceForText*pTickInfo->nFactorForLimitedTextWidth));
B2DVector aTickScreenPos2D( pTickInfo->aTickScreenPosition );
aTickScreenPos2D += aTextToTickDistance;
@@ -575,7 +723,7 @@ bool VCartesianAxis::createTextShapes(
if( doesOverlap( pLastVisibleNeighbourTickInfo->xTextShape, pTickInfo->xTextShape, m_aAxisLabelProperties.fRotationAngleDegree ) )
{
bool bOverlapAlsoAfterSwitchingOnAutoStaggering = true;
- if( !bIsStaggered && isAutoStaggeringOfLabelsAllowed( rAxisLabelProperties, pTickmarkHelper ) )
+ if( !bIsStaggered && isAutoStaggeringOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis ) )
{
bIsStaggered = true;
rAxisLabelProperties.eStaggering = STAGGER_EVEN;
@@ -583,7 +731,8 @@ bool VCartesianAxis::createTextShapes(
if( !pLastVisibleNeighbourTickInfo ||
!lcl_doesShapeOverlapWithTickmark( pLastVisibleNeighbourTickInfo->xTextShape
, rAxisLabelProperties.fRotationAngleDegree
- , pTickInfo->aTickScreenPosition, pTickmarkHelper ) )
+ , pTickInfo->aTickScreenPosition
+ , bIsHorizontalAxis, bIsVerticalAxis ) )
bOverlapAlsoAfterSwitchingOnAutoStaggering = false;
}
if( bOverlapAlsoAfterSwitchingOnAutoStaggering )
@@ -595,8 +744,7 @@ bool VCartesianAxis::createTextShapes(
continue;
}
rAxisLabelProperties.nRhythm++;
- TickIter aRemoveIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
- removeShapesAtWrongRythm( aRemoveIter, rAxisLabelProperties.nRhythm, nTick, xTarget );
+ removeShapesAtWrongRhythm( rTickIter, rAxisLabelProperties.nRhythm, nTick, xTarget );
return false;
}
}
@@ -1060,6 +1208,37 @@ TickmarkHelper_2D* VCartesianAxis::createTickmarkHelper2D()
return new TickmarkHelper_2D( m_aScale, m_aIncrement, aStart, aEnd, aLabelLineStart-aStart );
}
+void lcl_hideIdenticalScreenValues( TickIter& rTickIter )
+{
+ TickInfo* pPreviousTickInfo = rTickIter.firstInfo();
+ if(!pPreviousTickInfo)
+ return;
+ pPreviousTickInfo->bPaintIt = true;
+ for( TickInfo* pTickInfo = rTickIter.nextInfo(); pTickInfo; pTickInfo = rTickIter.nextInfo())
+ {
+ pTickInfo->bPaintIt =
+ ( static_cast<sal_Int32>(pTickInfo->aTickScreenPosition.getX())
+ != static_cast<sal_Int32>(pPreviousTickInfo->aTickScreenPosition.getX()) )
+ ||
+ ( static_cast<sal_Int32>(pTickInfo->aTickScreenPosition.getY())
+ != static_cast<sal_Int32>(pPreviousTickInfo->aTickScreenPosition.getY()) );
+ pPreviousTickInfo = pTickInfo;
+ }
+}
+
+//'hide' tickmarks with identical screen values in aAllTickInfos
+void VCartesianAxis::hideIdenticalScreenValues( ::std::vector< ::std::vector< TickInfo > >& rTickInfos ) const
+{
+ if( m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels )
+ {
+ sal_Int32 nCount = rTickInfos.size();
+ for( sal_Int32 nN=0; nN<nCount; nN++ )
+ lcl_hideIdenticalScreenValues( PureTickIter( rTickInfos[nN] ) );
+ }
+ else
+ lcl_hideIdenticalScreenValues( EquidistantTickIter( rTickInfos, m_aIncrement, 0, -1 ) );
+}
+
sal_Int32 VCartesianAxis::estimateMaximumAutoMainIncrementCount()
{
sal_Int32 nRet = 10;
@@ -1095,15 +1274,31 @@ void VCartesianAxis::doStaggeringOfLabels( const AxisLabelProperties& rAxisLabel
if( !pTickmarkHelper2D )
return;
- if( rAxisLabelProperties.getIsStaggered() )
+ if( m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels )
+ {
+ sal_Int32 nTextLevelCount = getTextLevelCount();
+ B2DVector aCummulatedLabelsDistance(0,0);
+ for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
+ {
+ ::std::auto_ptr< TickIter > apTickIter = createLabelTickIterator( nTextLevel );
+ if(apTickIter.get())
+ {
+ if( nTextLevel>0 )
+ lcl_shiftLables( *apTickIter.get(), aCummulatedLabelsDistance );
+ aCummulatedLabelsDistance += lcl_getLabelsDistance( *apTickIter.get()
+ , pTickmarkHelper2D->getDistanceAxisTickToText( m_aAxisProperties ) );
+ }
+ }
+ }
+ else if( rAxisLabelProperties.getIsStaggered() )
{
- LabelIterator aInnerIter( m_aAllTickInfos, m_aIncrement
+ EquidistantLabelIterator aInnerIter( m_aAllTickInfos, m_aIncrement
, rAxisLabelProperties.eStaggering, true, 0, 0 );
- LabelIterator aOuterIter( m_aAllTickInfos, m_aIncrement
+ EquidistantLabelIterator aOuterIter( m_aAllTickInfos, m_aIncrement
, rAxisLabelProperties.eStaggering, false, 0, 0 );
- lcl_correctPositionForStaggering( aOuterIter
- , lcl_getStaggerDistance( aInnerIter
+ lcl_shiftLables( aOuterIter
+ , lcl_getLabelsDistance( aInnerIter
, pTickmarkHelper2D->getDistanceAxisTickToText( m_aAxisProperties ) ) );
}
}
@@ -1127,18 +1322,30 @@ void SAL_CALL VCartesianAxis::createLabels()
pTickmarkHelper2D->updateScreenValues( m_aAllTickInfos );
//-----------------------------------------
//'hide' tickmarks with identical screen values in aAllTickInfos
- pTickmarkHelper2D->hideIdenticalScreenValues( m_aAllTickInfos );
+ hideIdenticalScreenValues( m_aAllTickInfos );
- TickIter aRemoveIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
- removeTextShapesFromTicks( aRemoveIter, m_xTextTarget );
+ removeTextShapesFromTicks();
//create tick mark text shapes
- TickIter aTickIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
- while( !createTextShapes( m_xTextTarget, aTickIter
- , m_aAxisLabelProperties, pTickmarkHelper2D ) )
+ sal_Int32 nTextLevelCount = getTextLevelCount();
+ sal_Int32 nScreenDistanceBetweenTicks = -1;
+ for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
{
- };
-
+ ::std::auto_ptr< TickIter > apTickIter = createLabelTickIterator( nTextLevel );
+ if(apTickIter.get())
+ {
+ if(nTextLevel==0)
+ nScreenDistanceBetweenTicks = TickmarkHelper_2D::getTickScreenDistance( *apTickIter.get() );
+
+ AxisLabelProperties aCopy(m_aAxisLabelProperties);
+ aCopy.bRhythmIsFix = true;
+ aCopy.nRhythm = 1;
+ AxisLabelProperties& rAxisLabelProperties = nTextLevel==0 ? m_aAxisLabelProperties : aCopy;
+ while( !createTextShapes( m_xTextTarget, *apTickIter.get(), rAxisLabelProperties, pTickmarkHelper2D, nScreenDistanceBetweenTicks ) )
+ {
+ };
+ }
+ }
doStaggeringOfLabels( m_aAxisLabelProperties, pTickmarkHelper2D );
}
}
@@ -1166,19 +1373,22 @@ void SAL_CALL VCartesianAxis::createMaximumLabels()
//create tick mark text shapes
//@todo: iterate through all tick depth wich should be labeled
- sal_Int32 nLongestLabelIndex = m_bUseTextLabels
- ? this->getIndexOfLongestLabel( m_aTextLabels ) : 0;
- MaxLabelTickIter aTickIter( m_aAllTickInfos, m_aIncrement, nLongestLabelIndex );
AxisLabelProperties aAxisLabelProperties( m_aAxisLabelProperties );
- if( isAutoStaggeringOfLabelsAllowed( aAxisLabelProperties, pTickmarkHelper2D ) )
+ if( isAutoStaggeringOfLabelsAllowed( aAxisLabelProperties, pTickmarkHelper2D->isHorizontalAxis(), pTickmarkHelper2D->isVerticalAxis() ) )
aAxisLabelProperties.eStaggering = STAGGER_EVEN;
aAxisLabelProperties.bOverlapAllowed = true;
aAxisLabelProperties.bLineBreakAllowed = false;
- while( !createTextShapes( m_xTextTarget, aTickIter
- , aAxisLabelProperties, pTickmarkHelper2D ) )
+ sal_Int32 nTextLevelCount = getTextLevelCount();
+ for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
{
- };
-
+ ::std::auto_ptr< TickIter > apTickIter = createMaximumLabelTickIterator( nTextLevel );
+ if(apTickIter.get())
+ {
+ while( !createTextShapes( m_xTextTarget, *apTickIter.get(), aAxisLabelProperties, pTickmarkHelper2D, -1 ) )
+ {
+ };
+ }
+ }
doStaggeringOfLabels( aAxisLabelProperties, pTickmarkHelper2D );
}
}
@@ -1198,46 +1408,47 @@ void SAL_CALL VCartesianAxis::updatePositions()
//update positions of all existing text shapes
pTickmarkHelper2D->updateScreenValues( m_aAllTickInfos );
- TickIter aTickIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
-
- Reference< drawing::XShape > xShape2DText;
- for( TickInfo* pTickInfo = aTickIter.firstInfo()
- ; pTickInfo; pTickInfo = aTickIter.nextInfo() )
+ ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = m_aAllTickInfos.begin();
+ const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = m_aAllTickInfos.end();
+ for( ; aDepthIter != aDepthEnd; aDepthIter++ )
{
- if( !pTickInfo )
- continue;
-
- xShape2DText = pTickInfo->xTextShape;
- if( xShape2DText.is() )
+ ::std::vector< TickInfo >::iterator aTickIter = aDepthIter->begin();
+ const ::std::vector< TickInfo >::const_iterator aTickEnd = aDepthIter->end();
+ for( ; aTickIter != aTickEnd; aTickIter++ )
{
- B2DVector aTextToTickDistance( pTickmarkHelper2D->getDistanceAxisTickToText( m_aAxisProperties ) );
- B2DVector aTickScreenPos2D( pTickInfo->aTickScreenPosition );
- aTickScreenPos2D += aTextToTickDistance;
- awt::Point aAnchorScreenPosition2D(
- static_cast<sal_Int32>(aTickScreenPos2D.getX())
- ,static_cast<sal_Int32>(aTickScreenPos2D.getY()));
-
- // #i78696# use mathematically correct rotation now
- const double fRotationAnglePi(m_aAxisLabelProperties.fRotationAngleDegree * (F_PI / -180.0));
- uno::Any aATransformation = ShapeFactory::makeTransformation(aAnchorScreenPosition2D, fRotationAnglePi);
-
- //set new position
- uno::Reference< beans::XPropertySet > xProp( xShape2DText, uno::UNO_QUERY );
- if( xProp.is() )
+ TickInfo& rTickInfo = (*aTickIter);
+ Reference< drawing::XShape > xShape2DText( rTickInfo.xTextShape );
+ if( xShape2DText.is() )
{
- try
+ B2DVector aTextToTickDistance( pTickmarkHelper2D->getDistanceAxisTickToText( m_aAxisProperties, true ) );
+ B2DVector aTickScreenPos2D( rTickInfo.aTickScreenPosition );
+ aTickScreenPos2D += aTextToTickDistance;
+ awt::Point aAnchorScreenPosition2D(
+ static_cast<sal_Int32>(aTickScreenPos2D.getX())
+ ,static_cast<sal_Int32>(aTickScreenPos2D.getY()));
+
+ // #i78696# use mathematically correct rotation now
+ const double fRotationAnglePi(m_aAxisLabelProperties.fRotationAngleDegree * (F_PI / -180.0));
+ uno::Any aATransformation = ShapeFactory::makeTransformation(aAnchorScreenPosition2D, fRotationAnglePi);
+
+ //set new position
+ uno::Reference< beans::XPropertySet > xProp( xShape2DText, uno::UNO_QUERY );
+ if( xProp.is() )
{
- xProp->setPropertyValue( C2U( "Transformation" ), aATransformation );
+ try
+ {
+ xProp->setPropertyValue( C2U( "Transformation" ), aATransformation );
+ }
+ catch( uno::Exception& e )
+ {
+ ASSERT_EXCEPTION( e );
+ }
}
- catch( uno::Exception& e )
- {
- ASSERT_EXCEPTION( e );
- }
- }
- //correctPositionForRotation
- LabelPositionHelper::correctPositionForRotation( xShape2DText
- , m_aAxisProperties.m_aLabelAlignment, m_aAxisLabelProperties.fRotationAngleDegree, false );
+ //correctPositionForRotation
+ LabelPositionHelper::correctPositionForRotation( xShape2DText
+ , m_aAxisProperties.m_aLabelAlignment, m_aAxisLabelProperties.fRotationAngleDegree, false );
+ }
}
}
@@ -1245,6 +1456,37 @@ void SAL_CALL VCartesianAxis::updatePositions()
}
}
+void VCartesianAxis::createTickMarkLineShapes( ::std::vector< TickInfo >& rTickInfos, const TickmarkProperties& rTickmarkProperties, TickmarkHelper_2D& rTickmarkHelper2D, bool bOnlyAtLabels )
+{
+ sal_Int32 nPointCount = rTickInfos.size();
+ drawing::PointSequenceSequence aPoints(2*nPointCount);
+
+ ::std::vector< TickInfo >::const_iterator aTickIter = rTickInfos.begin();
+ const ::std::vector< TickInfo >::const_iterator aTickEnd = rTickInfos.end();
+ sal_Int32 nN = 0;
+ for( ; aTickIter != aTickEnd; aTickIter++ )
+ {
+ if( !(*aTickIter).bPaintIt )
+ continue;
+
+ bool bTicksAtLabels = ( m_aAxisProperties.m_eTickmarkPos != ::com::sun::star::chart::ChartAxisMarkPosition_AT_AXIS );
+ double fInnerDirectionSign = m_aAxisProperties.m_fInnerDirectionSign;
+ if( bTicksAtLabels && m_aAxisProperties.m_eLabelPos == ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END )
+ fInnerDirectionSign *= -1.0;
+ bTicksAtLabels = bTicksAtLabels || bOnlyAtLabels;
+ //add ticks at labels:
+ rTickmarkHelper2D.addPointSequenceForTickLine( aPoints, nN++, (*aTickIter).fScaledTickValue
+ , fInnerDirectionSign , rTickmarkProperties, bTicksAtLabels );
+ //add ticks at axis (without lables):
+ if( !bOnlyAtLabels && m_aAxisProperties.m_eTickmarkPos == ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS )
+ rTickmarkHelper2D.addPointSequenceForTickLine( aPoints, nN++, (*aTickIter).fScaledTickValue
+ , m_aAxisProperties.m_fInnerDirectionSign, rTickmarkProperties, !bTicksAtLabels );
+ }
+ aPoints.realloc(nN);
+ m_pShapeFactory->createLine2D( m_xGroupShape_Shapes, aPoints
+ , &rTickmarkProperties.aLineProperties );
+}
+
void SAL_CALL VCartesianAxis::createShapes()
{
if( !prepareShapeCreation() )
@@ -1256,55 +1498,64 @@ void SAL_CALL VCartesianAxis::createShapes()
return;
//-----------------------------------------
- //create tick mark line shapes
+ //create line shapes
if(2==m_nDimension)
{
- ::std::vector< ::std::vector< TickInfo > > aAllShiftedTickInfos;
- if( m_aIncrement.ShiftedPosition )
- {
- pTickmarkHelper2D->getAllTicksShifted( aAllShiftedTickInfos );
- pTickmarkHelper2D->updateScreenValues( aAllShiftedTickInfos );
- pTickmarkHelper2D->hideIdenticalScreenValues( aAllShiftedTickInfos );
- }
- ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos = m_aIncrement.ShiftedPosition ? aAllShiftedTickInfos : m_aAllTickInfos;
-
- ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = rAllTickInfos.begin();
- const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = rAllTickInfos.end();
-
- if(aDepthIter == aDepthEnd)//no tickmarks at all
- return;
-
- sal_Int32 nTickmarkPropertiesCount = m_aAxisProperties.m_aTickmarkPropertiesList.size();
- for( sal_Int32 nDepth=0
- ; aDepthIter != aDepthEnd && nDepth < nTickmarkPropertiesCount
- ; aDepthIter++, nDepth++ )
+ //-----------------------------------------
+ //create extra long ticks to separate complex categories (create them only there where the labels are)
+ if( m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels )
{
- const TickmarkProperties& rTickmarkProperties = m_aAxisProperties.m_aTickmarkPropertiesList[nDepth];
-
- sal_Int32 nPointCount = (*aDepthIter).size();
- drawing::PointSequenceSequence aPoints(2*nPointCount);
+ ::std::vector< ::std::vector< TickInfo > > aComplexTickInfos;
+ createAllTickInfosFromComplexCategories( aComplexTickInfos, true );
+ pTickmarkHelper2D->updateScreenValues( aComplexTickInfos );
+ hideIdenticalScreenValues( aComplexTickInfos );
+
+ ::std::vector<TickmarkProperties> aTickmarkPropertiesList;
+ static bool bIncludeSpaceBetweenTickAndText = false;
+ sal_Int32 nOffset = pTickmarkHelper2D->getDistanceAxisTickToText( m_aAxisProperties, false, bIncludeSpaceBetweenTickAndText ).getLength();
+ sal_Int32 nTextLevelCount = getTextLevelCount();
+ for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
+ {
+ ::std::auto_ptr< TickIter > apTickIter = createLabelTickIterator( nTextLevel );
+ if( apTickIter.get() )
+ {
+ B2DVector aLabelsDistance( lcl_getLabelsDistance( *apTickIter.get(), pTickmarkHelper2D->getDistanceAxisTickToText( m_aAxisProperties, false ) ) );
+ sal_Int32 nCurrentLength = aLabelsDistance.getLength();
+ aTickmarkPropertiesList.push_back( m_aAxisProperties.makeTickmarkPropertiesForComplexCategories( nOffset + nCurrentLength, 0, nTextLevel ) );
+ nOffset += nCurrentLength;
+ }
+ }
- ::std::vector< TickInfo >::const_iterator aTickIter = (*aDepthIter).begin();
- const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end();
- sal_Int32 nN = 0;
- for( ; aTickIter != aTickEnd; aTickIter++ )
+ sal_Int32 nTickmarkPropertiesCount = aTickmarkPropertiesList.size();
+ ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = aComplexTickInfos.begin();
+ const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = aComplexTickInfos.end();
+ for( sal_Int32 nDepth=0; aDepthIter != aDepthEnd && nDepth < nTickmarkPropertiesCount; aDepthIter++, nDepth++ )
{
- if( !(*aTickIter).bPaintIt )
+ if(nDepth==0 && !m_aAxisProperties.m_nMajorTickmarks)
continue;
-
- bool bTicksAtLabels = ( m_aAxisProperties.m_eTickmarkPos != ::com::sun::star::chart::ChartAxisMarkPosition_AT_AXIS );
- double fInnerDirectionSign = m_aAxisProperties.m_fInnerDirectionSign;
- if( bTicksAtLabels && m_aAxisProperties.m_eLabelPos == ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END )
- fInnerDirectionSign *= -1.0;
- apTickmarkHelper2D->addPointSequenceForTickLine( aPoints, nN++, (*aTickIter).fScaledTickValue
- , fInnerDirectionSign , rTickmarkProperties, bTicksAtLabels );
- if( m_aAxisProperties.m_eTickmarkPos == ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS )
- apTickmarkHelper2D->addPointSequenceForTickLine( aPoints, nN++, (*aTickIter).fScaledTickValue
- , m_aAxisProperties.m_fInnerDirectionSign, rTickmarkProperties, !bTicksAtLabels );
+ createTickMarkLineShapes( *aDepthIter, aTickmarkPropertiesList[nDepth], *pTickmarkHelper2D, true /*bOnlyAtLabels*/ );
+ }
+ }
+ //-----------------------------------------
+ //create normal ticks for major and minor intervals
+ {
+ ::std::vector< ::std::vector< TickInfo > > aAllShiftedTickInfos;
+ if( m_aIncrement.ShiftedPosition || ( m_aAxisProperties.m_bComplexCategories && m_bUseTextLabels ) )
+ {
+ pTickmarkHelper2D->getAllTicksShifted( aAllShiftedTickInfos );
+ pTickmarkHelper2D->updateScreenValues( aAllShiftedTickInfos );
+ hideIdenticalScreenValues( aAllShiftedTickInfos );
}
- aPoints.realloc(nN);
- m_pShapeFactory->createLine2D( m_xGroupShape_Shapes, aPoints
- , &rTickmarkProperties.aLineProperties );
+ ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos = m_aIncrement.ShiftedPosition ? aAllShiftedTickInfos : m_aAllTickInfos;
+
+ ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = rAllTickInfos.begin();
+ const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = rAllTickInfos.end();
+ if(aDepthIter == aDepthEnd)//no tickmarks at all
+ return;
+
+ sal_Int32 nTickmarkPropertiesCount = m_aAxisProperties.m_aTickmarkPropertiesList.size();
+ for( sal_Int32 nDepth=0; aDepthIter != aDepthEnd && nDepth < nTickmarkPropertiesCount; aDepthIter++, nDepth++ )
+ createTickMarkLineShapes( *aDepthIter, m_aAxisProperties.m_aTickmarkPropertiesList[nDepth], *pTickmarkHelper2D, false /*bOnlyAtLabels*/ );
}
//-----------------------------------------
//create axis main lines
diff --git a/chart2/source/view/axes/VCartesianAxis.hxx b/chart2/source/view/axes/VCartesianAxis.hxx
index ef5c8a0bf613..060d841065d7 100644
--- a/chart2/source/view/axes/VCartesianAxis.hxx
+++ b/chart2/source/view/axes/VCartesianAxis.hxx
@@ -72,6 +72,12 @@ public:
virtual void SAL_CALL createShapes();
virtual sal_Int32 estimateMaximumAutoMainIncrementCount();
+ virtual void createAllTickInfos( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos );
+ void createAllTickInfosFromComplexCategories( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos, bool bShiftedPosition );
+
+ ::std::auto_ptr< TickIter > createLabelTickIterator( sal_Int32 nTextLevel );
+ ::std::auto_ptr< TickIter > createMaximumLabelTickIterator( sal_Int32 nTextLevel );
+ sal_Int32 getTextLevelCount() const;
//-------------------------------------------------------------------------
virtual TickmarkHelper* createTickmarkHelper();
@@ -117,16 +123,19 @@ protected: //methods
::com::sun::star::drawing::XShapes >& xTarget
, TickIter& rTickIter
, AxisLabelProperties& rAxisLabelProperties
- , TickmarkHelper_2D* pTickmarkHelper );
+ , TickmarkHelper_2D* pTickmarkHelper
+ , sal_Int32 nScreenDistanceBetweenTicks );
+
+ void createTickMarkLineShapes( ::std::vector< TickInfo >& rTickInfos, const TickmarkProperties& rTickmarkProperties, TickmarkHelper_2D& rTickmarkHelper2D, bool bOnlyAtLabels );
TickmarkHelper_2D* createTickmarkHelper2D();
+ void hideIdenticalScreenValues( ::std::vector< ::std::vector< TickInfo > >& rTickInfos ) const;
void doStaggeringOfLabels( const AxisLabelProperties& rAxisLabelProperties
, TickmarkHelper_2D* pTickmarkHelper2D );
bool isAutoStaggeringOfLabelsAllowed( const AxisLabelProperties& rAxisLabelProperties
- , TickmarkHelper_2D* pTickmarkHelper);
- bool isBreakOfLabelsAllowed( const AxisLabelProperties& rAxisLabelProperties
- , TickmarkHelper_2D* pTickmarkHelper );
+ , bool bIsHorizontalAxis, bool bIsVerticalAxis );
+ bool isBreakOfLabelsAllowed( const AxisLabelProperties& rAxisLabelProperties, bool bIsHorizontalAxis );
::basegfx::B2DVector getScreenPosition( double fLogicX, double fLogicY, double fLogicZ ) const;
ScreenPosAndLogicPos getScreenPosAndLogicPos( double fLogicX, double fLogicY, double fLogicZ ) const;
diff --git a/chart2/source/view/axes/VCartesianCoordinateSystem.cxx b/chart2/source/view/axes/VCartesianCoordinateSystem.cxx
index e6e77ebea57a..489653aac03f 100644
--- a/chart2/source/view/axes/VCartesianCoordinateSystem.cxx
+++ b/chart2/source/view/axes/VCartesianCoordinateSystem.cxx
@@ -156,7 +156,8 @@ void VCartesianCoordinateSystem::createVAxisList(
if( aCrossingScale.AxisType == AxisType::CATEGORY )
{
aAxisProperties.m_bCrossingAxisIsCategoryAxes = true;
- aAxisProperties.m_bAxisBetweenCategories = ChartTypeHelper::shiftTicksAtXAxisPerDefault( AxisHelper::getChartTypeByIndex( m_xCooSysModel, 0 ) );
+ aAxisProperties.m_bAxisBetweenCategories = ChartTypeHelper::shiftTicksAtXAxisPerDefault( AxisHelper::getChartTypeByIndex( m_xCooSysModel, 0 ) )
+ || ( aAxisProperties.m_pExplicitCategoriesProvider && aAxisProperties.m_pExplicitCategoriesProvider->hasComplexCategories() );
}
}
@@ -171,6 +172,13 @@ void VCartesianCoordinateSystem::createVAxisList(
aAxisProperties.init(true);
if(aAxisProperties.m_bDisplayLabels)
aAxisProperties.m_nNumberFormatKey = this->getNumberFormatKeyForAxis( xAxis, xNumberFormatsSupplier );
+
+ if( nDimensionIndex == 0 && aAxisProperties.m_nAxisType == AxisType::CATEGORY
+ && aAxisProperties.m_pExplicitCategoriesProvider )
+ {
+ if( aAxisProperties.m_pExplicitCategoriesProvider->hasComplexCategories() )
+ aAxisProperties.m_bComplexCategories = true;
+ }
//-------------------
::boost::shared_ptr< VAxisBase > apVAxis( new VCartesianAxis(aAxisProperties,xNumberFormatsSupplier,nDimensionIndex,nDimensionCount) );
tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex );
diff --git a/chart2/source/view/axes/VPolarAngleAxis.cxx b/chart2/source/view/axes/VPolarAngleAxis.cxx
index 1aa56efbca78..6a177938d725 100644
--- a/chart2/source/view/axes/VPolarAngleAxis.cxx
+++ b/chart2/source/view/axes/VPolarAngleAxis.cxx
@@ -65,7 +65,7 @@ VPolarAngleAxis::~VPolarAngleAxis()
bool VPolarAngleAxis::createTextShapes_ForAngleAxis(
const uno::Reference< drawing::XShapes >& xTarget
- , TickIter& rTickIter
+ , EquidistantTickIter& rTickIter
, AxisLabelProperties& rAxisLabelProperties
, double fLogicRadius
, double fLogicZ )
@@ -102,7 +102,7 @@ bool VPolarAngleAxis::createTextShapes_ForAngleAxis(
; pTickInfo
; pTickInfo = rTickIter.nextInfo(), nTick++ )
{
- //don't create labels which does not fit into the rythm
+ //don't create labels which does not fit into the rhythm
if( nTick%rAxisLabelProperties.nRhythm != 0)
continue;
@@ -192,11 +192,10 @@ void SAL_CALL VPolarAngleAxis::createLabels()
//create tick mark text shapes
//@todo: iterate through all tick depth wich should be labeled
- TickIter aTickIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
+ EquidistantTickIter aTickIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
this->updateUnscaledValuesAtTicks( aTickIter );
- TickIter aRemoveIter( m_aAllTickInfos, m_aIncrement, 0, 0 );
- removeTextShapesFromTicks( aRemoveIter, m_xTextTarget );
+ removeTextShapesFromTicks();
AxisLabelProperties aAxisLabelProperties( m_aAxisLabelProperties );
aAxisLabelProperties.bOverlapAllowed = true;
diff --git a/chart2/source/view/axes/VPolarAngleAxis.hxx b/chart2/source/view/axes/VPolarAngleAxis.hxx
index a04318b70ee1..0f20259b2572 100644
--- a/chart2/source/view/axes/VPolarAngleAxis.hxx
+++ b/chart2/source/view/axes/VPolarAngleAxis.hxx
@@ -58,7 +58,7 @@ public:
private: //methods
bool createTextShapes_ForAngleAxis(
const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget
- , TickIter& rTickIter
+ , EquidistantTickIter& rTickIter
, AxisLabelProperties& rAxisLabelProperties
, double fLogicRadius, double fLogicZ );
};
diff --git a/chart2/source/view/axes/VPolarGrid.cxx b/chart2/source/view/axes/VPolarGrid.cxx
index f9278b94b245..9ed18040f44f 100644
--- a/chart2/source/view/axes/VPolarGrid.cxx
+++ b/chart2/source/view/axes/VPolarGrid.cxx
@@ -93,7 +93,7 @@ void VPolarGrid::createLinePointSequence_ForAngleAxis(
xInverseScaling = rScale.Scaling->getInverseScaling();
sal_Int32 nTick = 0;
- TickIter aIter( rAllTickInfos, rIncrement, 0, 0 );
+ EquidistantTickIter aIter( rAllTickInfos, rIncrement, 0, 0 );
for( TickInfo* pTickInfo = aIter.firstInfo()
; pTickInfo
; pTickInfo = aIter.nextInfo(), nTick++ )
diff --git a/chart2/source/view/axes/VPolarRadiusAxis.cxx b/chart2/source/view/axes/VPolarRadiusAxis.cxx
index 2b3fdf5c327c..4fe7e87fce3e 100644
--- a/chart2/source/view/axes/VPolarRadiusAxis.cxx
+++ b/chart2/source/view/axes/VPolarRadiusAxis.cxx
@@ -52,7 +52,6 @@ VPolarRadiusAxis::VPolarRadiusAxis( const AxisProperties& rAxisProperties
{
m_aAxisProperties.m_fLabelDirectionSign=0.0;
m_aAxisProperties.m_fInnerDirectionSign=0.0;
- m_aAxisProperties.m_bLabelsOutside=true;
m_aAxisProperties.m_bIsMainAxis=false;
m_aAxisProperties.m_aLabelAlignment=LABEL_ALIGN_RIGHT;
m_aAxisProperties.init();
@@ -159,7 +158,7 @@ void SAL_CALL VPolarRadiusAxis::createShapes()
AxisProperties aAxisProperties(m_aAxisProperties);
sal_Int32 nTick = 0;
- TickIter aIter( aAngleTickInfos, rAngleIncrement, 0, 0 );
+ EquidistantTickIter aIter( aAngleTickInfos, rAngleIncrement, 0, 0 );
for( TickInfo* pTickInfo = aIter.firstInfo()
; pTickInfo; pTickInfo = aIter.nextInfo(), nTick++ )
{
diff --git a/chart2/source/view/charttypes/AreaChart.cxx b/chart2/source/view/charttypes/AreaChart.cxx
index 406e5d119cd6..20a5f174f10f 100644
--- a/chart2/source/view/charttypes/AreaChart.cxx
+++ b/chart2/source/view/charttypes/AreaChart.cxx
@@ -75,7 +75,6 @@ AreaChart::AreaChart( const uno::Reference<XChartType>& xChartTypeModel
, bool bNoArea
, PlottingPositionHelper* pPlottingPositionHelper
, bool bConnectLastToFirstPoint
- , bool bAddOneToXMax
, bool bExpandIfValuesCloseToBorder
, sal_Int32 nKeepAspectRatio
, const drawing::Direction3D& rAspectRatio
@@ -87,7 +86,6 @@ AreaChart::AreaChart( const uno::Reference<XChartType>& xChartTypeModel
, m_bSymbol( ChartTypeHelper::isSupportingSymbolProperties(xChartTypeModel,nDimensionCount) )
, m_bIsPolarCooSys( bConnectLastToFirstPoint )
, m_bConnectLastToFirstPoint( bConnectLastToFirstPoint )
- , m_bAddOneToXMax(bAddOneToXMax)
, m_bExpandIfValuesCloseToBorder( bExpandIfValuesCloseToBorder )
, m_nKeepAspectRatio(nKeepAspectRatio)
, m_aGivenAspectRatio(rAspectRatio)
@@ -126,14 +124,17 @@ AreaChart::~AreaChart()
delete m_pMainPosHelper;
}
+double AreaChart::getMinimumX()
+{
+ if( m_bCategoryXAxis && m_bIsPolarCooSys )//the angle axis in net charts needs a different autoscaling
+ return 1.0;//first category (index 0) matches with real number 1.0
+ return VSeriesPlotter::getMinimumX();
+}
+
double AreaChart::getMaximumX()
{
- if( m_bAddOneToXMax )
- {
- //return category count
- sal_Int32 nPointCount = getPointCount();
- return nPointCount+1;
- }
+ if( m_bCategoryXAxis && m_bIsPolarCooSys )//the angle axis in net charts needs a different autoscaling
+ return getPointCount()+1;
return VSeriesPlotter::getMaximumX();
}
diff --git a/chart2/source/view/charttypes/AreaChart.hxx b/chart2/source/view/charttypes/AreaChart.hxx
index ec90e92ba1a4..e941c7094e27 100644
--- a/chart2/source/view/charttypes/AreaChart.hxx
+++ b/chart2/source/view/charttypes/AreaChart.hxx
@@ -52,7 +52,6 @@ public:
, bool bCategoryXAxis, bool bNoArea=false
, PlottingPositionHelper* pPlottingPositionHelper=NULL //takes owner ship
, bool bConnectLastToFirstPoint=false
- , bool bAddOneToXMax=false
, bool bExpandIfValuesCloseToBorder=true
, sal_Int32 nKeepAspectRatio=-1 //0->no 1->yes other value->automatic
, const ::com::sun::star::drawing::Direction3D& rAspectRatio=::com::sun::star::drawing::Direction3D(1,1,1)//only taken into account if nKeepAspectRatio==1
@@ -79,6 +78,7 @@ public:
//-------------------------------------------------------------------------
// MinimumAndMaximumSupplier
//-------------------------------------------------------------------------
+ virtual double getMinimumX();
virtual double getMaximumX();
virtual bool isExpandIfValuesCloseToBorder( sal_Int32 nDimensionIndex );
virtual bool isSeperateStackingForDifferentSigns( sal_Int32 nDimensionIndex );
@@ -112,7 +112,6 @@ private: //member
bool m_bSymbol;
bool m_bIsPolarCooSys;//used e.g. for net chart (the data labels need to be placed different)
bool m_bConnectLastToFirstPoint;//used e.g. for net chart
- bool m_bAddOneToXMax;//used e.g. for net chart (the angle axis needs a different autoscaling)
bool m_bExpandIfValuesCloseToBorder; // e.g. false for net charts
sal_Int32 m_nKeepAspectRatio; //0->no 1->yes other value->automatic
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index f1f9d0ce8ce6..e83596a02b61 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -482,7 +482,7 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re
{
if( m_pExplicitCategoriesProvider )
{
- Sequence< OUString > aCategories( m_pExplicitCategoriesProvider->getTextualData() );
+ Sequence< OUString > aCategories( m_pExplicitCategoriesProvider->getSimpleCategories() );
if( nPointIndex >= 0 && nPointIndex < aCategories.getLength() )
{
aText.append( aCategories[nPointIndex] );
@@ -1127,7 +1127,12 @@ void VSeriesPlotter::setMappedProperties(
double VSeriesPlotter::getMinimumX()
{
if( m_bCategoryXAxis )
- return 1.0;//first category (index 0) matches with real number 1.0
+ {
+ double fRet = 1.0;//first category (index 0) matches with real number 1.0
+ if( m_pExplicitCategoriesProvider && m_pExplicitCategoriesProvider->hasComplexCategories() )
+ fRet -= 0.5;
+ return fRet;
+ }
double fMinimum, fMaximum;
this->getMinimumAndMaximiumX( fMinimum, fMaximum );
@@ -1138,8 +1143,10 @@ double VSeriesPlotter::getMaximumX()
if( m_bCategoryXAxis )
{
//return category count
- sal_Int32 nPointCount = getPointCount();
- return nPointCount;//first category (index 0) matches with real number 1.0
+ double fRet = getPointCount();//first category (index 0) matches with real number 1.0
+ if( m_pExplicitCategoriesProvider && m_pExplicitCategoriesProvider->hasComplexCategories() )
+ fRet += 0.5;
+ return fRet;
}
double fMinimum, fMaximum;
@@ -1930,7 +1937,7 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForSe
{
Sequence< OUString > aCategoryNames;
if( m_pExplicitCategoriesProvider )
- aCategoryNames = m_pExplicitCategoriesProvider->getTextualData();
+ aCategoryNames = m_pExplicitCategoriesProvider->getSimpleCategories();
for( sal_Int32 nIdx=0; nIdx<aCategoryNames.getLength(); ++nIdx )
{
@@ -2074,9 +2081,9 @@ VSeriesPlotter* VSeriesPlotter::createSeriesPlotter(
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
pRet = new PieChart(xChartTypeModel,nDimensionCount);
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
- pRet = new AreaChart(xChartTypeModel,nDimensionCount,true,true,new PolarPlottingPositionHelper(),true,true,false,1,drawing::Direction3D(1,1,1) );
+ pRet = new AreaChart(xChartTypeModel,nDimensionCount,true,true,new PolarPlottingPositionHelper(),true,false,1,drawing::Direction3D(1,1,1) );
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
- pRet = new AreaChart(xChartTypeModel,nDimensionCount,true,false,new PolarPlottingPositionHelper(),true,true,false,1,drawing::Direction3D(1,1,1) );
+ pRet = new AreaChart(xChartTypeModel,nDimensionCount,true,false,new PolarPlottingPositionHelper(),true,false,1,drawing::Direction3D(1,1,1) );
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
pRet = new CandleStickChart(xChartTypeModel,nDimensionCount);
else
diff --git a/chart2/source/view/inc/PropertyMapper.hxx b/chart2/source/view/inc/PropertyMapper.hxx
index 57227e7f6292..0e21cc617b04 100644
--- a/chart2/source/view/inc/PropertyMapper.hxx
+++ b/chart2/source/view/inc/PropertyMapper.hxx
@@ -91,6 +91,11 @@ public:
, const tNameSequence& rPropNames
, const rtl::OUString& rPropName );
+ static ::com::sun::star::uno::Any*
+ getValuePointerForLimitedSpace( tAnySequence& rPropValues
+ , const tNameSequence& rPropNames
+ , bool bLimitedHeight );
+
static void setMultiProperties(
const tNameSequence& rNames
, const tAnySequence& rValues
diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx
index 8da5c2772493..b7a54a154fbf 100644
--- a/chart2/source/view/main/ChartView.cxx
+++ b/chart2/source/view/main/ChartView.cxx
@@ -577,13 +577,13 @@ private:
std::vector< VCoordinateSystem* >& m_rVCooSysList;
::std::map< uno::Reference< XAxis >, AxisUsage > m_aAxisUsageList;
sal_Int32 m_nMaxAxisIndex;
- bool m_bShiftXAxisTicks;
+ bool m_bChartTypeUsesShiftedXAxisTicksPerDefault;
};
SeriesPlotterContainer::SeriesPlotterContainer( std::vector< VCoordinateSystem* >& rVCooSysList )
: m_rVCooSysList( rVCooSysList )
, m_nMaxAxisIndex(0)
- , m_bShiftXAxisTicks(false)
+ , m_bChartTypeUsesShiftedXAxisTicksPerDefault(false)
{
}
@@ -678,7 +678,7 @@ void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(
uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
if(nT==0)
- m_bShiftXAxisTicks = ChartTypeHelper::shiftTicksAtXAxisPerDefault( xChartType );
+ m_bChartTypeUsesShiftedXAxisTicksPerDefault = ChartTypeHelper::shiftTicksAtXAxisPerDefault( xChartType );
VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount );
if( !pPlotter )
@@ -932,7 +932,9 @@ void SeriesPlotterContainer::doAutoScaling( const uno::Reference< frame::XModel
for( nC=0; nC < aVCooSysList_X.size(); nC++)
{
- if( m_bShiftXAxisTicks )
+ ExplicitCategoriesProvider* pExplicitCategoriesProvider = aVCooSysList_X[nC]->getExplicitCategoriesProvider();
+
+ if( m_bChartTypeUsesShiftedXAxisTicksPerDefault || (aExplicitScale.AxisType==AxisType::CATEGORY && pExplicitCategoriesProvider && pExplicitCategoriesProvider->hasComplexCategories() ) )
aExplicitIncrement.ShiftedPosition = true;
aVCooSysList_X[nC]->setExplicitScaleAndIncrement( 0, nAxisIndex, aExplicitScale, aExplicitIncrement );
}
diff --git a/chart2/source/view/main/PropertyMapper.cxx b/chart2/source/view/main/PropertyMapper.cxx
index 04d95ce249a6..efbadab9a4c8 100644
--- a/chart2/source/view/main/PropertyMapper.cxx
+++ b/chart2/source/view/main/PropertyMapper.cxx
@@ -168,6 +168,14 @@ uno::Any* PropertyMapper::getValuePointer( tAnySequence& rPropValues
return NULL;
}
+uno::Any* PropertyMapper::getValuePointerForLimitedSpace( tAnySequence& rPropValues
+ , const tNameSequence& rPropNames
+ , bool bLimitedHeight)
+{
+ return PropertyMapper::getValuePointer( rPropValues, rPropNames
+ , bLimitedHeight ? C2U("TextMaximumFrameHeight") : C2U("TextMaximumFrameWidth") );
+}
+
/*
//set some properties from service style::CharacterProperties:
//-------- tabpage: Zeichen -----------