diff options
author | Björn Milcke <bm@openoffice.org> | 2003-10-06 08:58:36 +0000 |
---|---|---|
committer | Björn Milcke <bm@openoffice.org> | 2003-10-06 08:58:36 +0000 |
commit | 668c6b0245b6076ac8fb3f5d734795117188675e (patch) | |
tree | 363512534f7fae13719bddccb3a365e48ef7a8d3 /chart2/source/view/axes | |
parent | INTEGRATION: CWS os20 (1.10.256); FILE MERGED (diff) | |
download | core-668c6b0245b6076ac8fb3f5d734795117188675e.tar.gz core-668c6b0245b6076ac8fb3f5d734795117188675e.zip |
initial import
Diffstat (limited to 'chart2/source/view/axes')
-rw-r--r-- | chart2/source/view/axes/ScaleAutomatism.cxx | 357 | ||||
-rw-r--r-- | chart2/source/view/axes/TickmarkHelper.cxx | 797 | ||||
-rw-r--r-- | chart2/source/view/axes/TickmarkHelper.hxx | 265 | ||||
-rw-r--r-- | chart2/source/view/axes/VAxisProperties.cxx | 468 | ||||
-rw-r--r-- | chart2/source/view/axes/VCoordinateSystem.cxx | 226 | ||||
-rw-r--r-- | chart2/source/view/axes/makefile.mk | 91 |
6 files changed, 2204 insertions, 0 deletions
diff --git a/chart2/source/view/axes/ScaleAutomatism.cxx b/chart2/source/view/axes/ScaleAutomatism.cxx new file mode 100644 index 000000000000..6f9c14700778 --- /dev/null +++ b/chart2/source/view/axes/ScaleAutomatism.cxx @@ -0,0 +1,357 @@ +/************************************************************************* + * + * $RCSfile: ScaleAutomatism.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2003 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include "ScaleAutomatism.hxx" +#include "macros.hxx" +#include "TickmarkHelper.hxx" + +#ifndef _COM_SUN_STAR_LANG_XSERVICENAME_HPP_ +#include <com/sun/star/lang/XServiceName.hpp> +#endif + +#ifndef INCLUDED_RTL_MATH_HXX +#include <rtl/math.hxx> +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +//............................................................................. +namespace chart +{ +//............................................................................. +using namespace ::com::sun::star; +using namespace ::drafts::com::sun::star::chart2; + +ScaleAutomatism::ScaleAutomatism( const ScaleData& rSourceScale ) + : m_fValueMinimum( 0.0 ) + , m_fValueMaximum( 0.0 ) + , m_nMaximumAutomaticMainIncrementCount(10) + , m_aSourceScale( rSourceScale ) + , m_aSourceIncrement() + , m_aSourceSubIncrementList() +{ + ::rtl::math::setNan( &m_fValueMinimum ); + ::rtl::math::setNan( &m_fValueMaximum ); +} + +ScaleAutomatism::ScaleAutomatism( const ScaleData& rSourceScale + , const IncrementData& rSourceIncrement + , const uno::Sequence< SubIncrement >& rSourceSubIncrementList ) + : m_fValueMinimum( 0.0 ) + , m_fValueMaximum( 0.0 ) + , m_nMaximumAutomaticMainIncrementCount(9) + , m_aSourceScale( rSourceScale ) + , m_aSourceIncrement( rSourceIncrement ) + , m_aSourceSubIncrementList( rSourceSubIncrementList ) +{ + ::rtl::math::setNan( &m_fValueMinimum ); + ::rtl::math::setNan( &m_fValueMaximum ); +} + +ScaleAutomatism::~ScaleAutomatism() +{ +} + +//@todo these method should become part of the scaling interface and implementation somehow +//@todo problem with outparamters at api +ExplicitIncrementData getExplicitIncrementAndScaleForLogarithm( + bool bChangeMinimumToIncrementRythm, bool bChangeMaximumToIncrementRythm + , sal_Int32 nMaximumAutomaticMainIncrementCount + , ExplicitScaleData& rExplicitScale + , const IncrementData& rSourceIncrement + , const uno::Sequence< SubIncrement >& rSourceSubIncrementList ) +{ + //minimum and maximum of the ExplicitScaleData may be changed + //to suiteable values if allowed + //but they will definitly be changed if they are out of allowed borders + + if( nMaximumAutomaticMainIncrementCount <= 0 ) + nMaximumAutomaticMainIncrementCount = 5; + + //make sure that minimum and maximum are not out of allowed range + { + if( rExplicitScale.Maximum<=0.0 ) + rExplicitScale.Maximum = 100.0; + if( rExplicitScale.Minimum<=0.0 ) + { + rExplicitScale.Minimum = 0.1; + if( rExplicitScale.Minimum >= rExplicitScale.Maximum ) + rExplicitScale.Minimum = log(rExplicitScale.Maximum)/10.0; + } + } + + ExplicitIncrementData aRet; + if(!(rSourceIncrement.PostEquidistant>>=aRet.PostEquidistant)) + { + //maybe scaling dependent + aRet.PostEquidistant = sal_True; + } + if(!(rSourceIncrement.Distance>>=aRet.Distance)) + { + //autocalculate the distance + if(aRet.PostEquidistant && rExplicitScale.Scaling.is() ) + { + double fRange = rExplicitScale.Scaling->doScaling( rExplicitScale.Maximum ) + - rExplicitScale.Scaling->doScaling( rExplicitScale.Minimum ); + double fSlice = fRange/nMaximumAutomaticMainIncrementCount; + //make a fine value out of fSlice now: + //only integers are reasonable as distance values + sal_Int32 nDistance = static_cast<sal_Int32>(fSlice); + if(nDistance<=0) + nDistance=1; + aRet.Distance = nDistance; + } + else + { + //@todo this was not tested + double fRange = rExplicitScale.Maximum - rExplicitScale.Minimum; + double fSlice = fRange/nMaximumAutomaticMainIncrementCount; + //make a fine value out of fSlice now: + double fSliceMagnitude = pow (10, floor (log10 (fSlice))); + aRet.Distance = static_cast<sal_Int32>(fSlice/fSliceMagnitude)*fSliceMagnitude; + } + } + + if(!(rSourceIncrement.BaseValue>>=aRet.BaseValue)) + { + //scaling dependent + //@maybe todo is this default also plotter dependent ?? + aRet.BaseValue = 1.0; + } + else if( aRet.BaseValue<=0.0 ) //make sure that BaseValue is not out of allowed ranges + aRet.BaseValue = 1.0; + + if(bChangeMinimumToIncrementRythm) + { + double fMin = rExplicitScale.Minimum; + if( aRet.PostEquidistant && rExplicitScale.Scaling.is() ) + fMin = rExplicitScale.Scaling->doScaling(fMin); + + fMin = TickmarkHelper::getMinimumAtIncrement( fMin, aRet ); + if( aRet.PostEquidistant && rExplicitScale.Scaling.is() ) + fMin = rExplicitScale.Scaling->getInverseScaling()->doScaling(fMin); + rExplicitScale.Minimum = fMin; + + if( rExplicitScale.Minimum<=0.0 ) + { + rExplicitScale.Minimum = 0.1; + if( rExplicitScale.Minimum >= rExplicitScale.Maximum ) + rExplicitScale.Minimum = log(rExplicitScale.Maximum)/10.0; + } + } + if(bChangeMaximumToIncrementRythm) + { + double fMax = rExplicitScale.Maximum; + if( aRet.PostEquidistant && rExplicitScale.Scaling.is() ) + fMax = rExplicitScale.Scaling->doScaling(fMax); + fMax = TickmarkHelper::getMaximumAtIncrement( fMax, aRet ); + if( aRet.PostEquidistant && rExplicitScale.Scaling.is() ) + fMax = rExplicitScale.Scaling->getInverseScaling()->doScaling(fMax); + rExplicitScale.Maximum = fMax; + } + //--------------------------------------------------------------- + //fill explicit sub increment + sal_Int32 nSubCount = rSourceSubIncrementList.getLength(); + aRet.SubIncrements.realloc(nSubCount); + for( sal_Int32 nN=0; nN<nSubCount; nN++ ) + { + const SubIncrement& rSubIncrement = rSourceSubIncrementList[nN]; + ExplicitSubIncrement& rExplicitSubIncrement = aRet.SubIncrements[nN]; + + if(!(rSubIncrement.IntervalCount>>=rExplicitSubIncrement.IntervalCount)) + { + //scaling dependent + //@todo autocalculate IntervalCount dependent on MainIncrement and scaling + rExplicitSubIncrement.IntervalCount = 5; + } + if(!(rSubIncrement.PostEquidistant>>=rExplicitSubIncrement.PostEquidistant)) + { + //scaling dependent + rExplicitSubIncrement.PostEquidistant = sal_False; + } + } + return aRet; +} + +ExplicitIncrementData getExplicitIncrementAndScaleForLinear( + bool bChangeMinimumToIncrementRythm, bool bChangeMaximumToIncrementRythm + , sal_Int32 nMaximumAutomaticMainIncrementCount + , ExplicitScaleData& rExplicitScale + , const IncrementData& rSourceIncrement + , const uno::Sequence< SubIncrement >& rSourceSubIncrementList ) +{ + //minimum and maximum of the ExplicitScaleData may be changed + //to suiteable values if allowed + //but they will definitly be changed if they are out of allowed borders + + ExplicitIncrementData aRet; + if(!(rSourceIncrement.PostEquidistant>>=aRet.PostEquidistant)) + { + //maybe scaling dependent + aRet.PostEquidistant = sal_True; + } + if(!(rSourceIncrement.Distance>>=aRet.Distance)) + { + //autocalculate the distance + double fRange = rExplicitScale.Maximum - rExplicitScale.Minimum; + double fSlice = fRange/nMaximumAutomaticMainIncrementCount; + + //make a fine value out of fSlice now: + double fSliceMagnitude = pow (10, floor (log10 (fSlice))); + fSlice /= fSliceMagnitude; + if(fSlice<=1.0) + fSlice=1.0; + else if( fSlice<= 2.0 ) + fSlice=2.0; + else if( fSlice<= 2.5 ) + fSlice=2.5; + else if( fSlice<= 5.0) + fSlice=5.0; + else + fSlice=10.0; + + aRet.Distance = fSlice*fSliceMagnitude; + } + if(!(rSourceIncrement.BaseValue>>=aRet.BaseValue)) + { + //@maybe todo is this default also plotter dependent ?? + aRet.BaseValue = 0.0; + } + if(bChangeMinimumToIncrementRythm) + { + rExplicitScale.Minimum = TickmarkHelper::getMinimumAtIncrement( rExplicitScale.Minimum, aRet ); + } + if(bChangeMaximumToIncrementRythm) + { + rExplicitScale.Maximum = TickmarkHelper::getMaximumAtIncrement( rExplicitScale.Maximum, aRet ); + } + //--------------------------------------------------------------- + //fill explicit sub increment + sal_Int32 nSubCount = rSourceSubIncrementList.getLength(); + aRet.SubIncrements.realloc(nSubCount); + for( sal_Int32 nN=0; nN<nSubCount; nN++ ) + { + const SubIncrement& rSubIncrement = rSourceSubIncrementList[nN]; + ExplicitSubIncrement& rExplicitSubIncrement = aRet.SubIncrements[nN]; + + if(!(rSubIncrement.IntervalCount>>=rExplicitSubIncrement.IntervalCount)) + { + //scaling dependent + //@todo autocalculate IntervalCount dependent on MainIncrement and scaling + rExplicitSubIncrement.IntervalCount = 2; + } + if(!(rSubIncrement.PostEquidistant>>=rExplicitSubIncrement.PostEquidistant)) + { + //scaling dependent + rExplicitSubIncrement.PostEquidistant = sal_False; + } + } + return aRet; +} + +void ScaleAutomatism::calculateExplicitScaleAndIncrement( + ExplicitScaleData& rExplicitScale + , ExplicitIncrementData& rExplicitIncrement ) +{ + //--------------------------------------------------------------- + //fill explicit scale + bool bChangeMinimumToIncrementRythm=false, bChangeMaximumToIncrementRythm=false; + if(!(m_aSourceScale.Minimum>>=rExplicitScale.Minimum)) + { + //autocalculate the minimum in first iteration + //the increment is considered below + if( !::rtl::math::isNan(m_fValueMinimum) ) + rExplicitScale.Minimum = m_fValueMinimum; + else + rExplicitScale.Minimum = 0.0;//@todo get Minimum from scsaling or from plotter???? + bChangeMinimumToIncrementRythm = true; + } + if(!(m_aSourceScale.Maximum>>=rExplicitScale.Maximum)) + { + //autocalculate the maximum in first iteration + //the increment is considered below + if( !::rtl::math::isNan(m_fValueMaximum) ) + rExplicitScale.Maximum = m_fValueMaximum; + else + rExplicitScale.Maximum = 10.0;//@todo get Maximum from scaling or from plotter???? + bChangeMaximumToIncrementRythm=true; + } + rExplicitScale.Orientation = m_aSourceScale.Orientation;//AxisOrientation_MATHEMATICAL; + rExplicitScale.Scaling = m_aSourceScale.Scaling; + rExplicitScale.Breaks = m_aSourceScale.Breaks; + //--------------------------------------------------------------- + //fill explicit increment + //minimum and maximum of the ExplicitScaleData may be changed if allowed + uno::Reference< lang::XServiceName > xServiceName( rExplicitScale.Scaling, uno::UNO_QUERY ); + bool bIsLogarithm = ( xServiceName.is() && (xServiceName->getServiceName()).equals( + C2U( "com.sun.star.chart2.LogarithmicScaling" ))); + if(bIsLogarithm) + rExplicitIncrement = getExplicitIncrementAndScaleForLogarithm( bChangeMinimumToIncrementRythm, bChangeMaximumToIncrementRythm, m_nMaximumAutomaticMainIncrementCount + , rExplicitScale, m_aSourceIncrement, m_aSourceSubIncrementList ); + else + rExplicitIncrement = getExplicitIncrementAndScaleForLinear( bChangeMinimumToIncrementRythm, bChangeMaximumToIncrementRythm, m_nMaximumAutomaticMainIncrementCount + , rExplicitScale, m_aSourceIncrement, m_aSourceSubIncrementList ); +} + +//............................................................................. +} //namespace chart +//............................................................................. diff --git a/chart2/source/view/axes/TickmarkHelper.cxx b/chart2/source/view/axes/TickmarkHelper.cxx new file mode 100644 index 000000000000..5c2563f134a7 --- /dev/null +++ b/chart2/source/view/axes/TickmarkHelper.cxx @@ -0,0 +1,797 @@ +/************************************************************************* + * + * $RCSfile: TickmarkHelper.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2003 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include "TickmarkHelper.hxx" +#include "ViewDefines.hxx" + +#ifndef INCLUDED_RTL_MATH_HXX +#include <rtl/math.hxx> +#endif +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +//............................................................................. +namespace chart +{ +//............................................................................. +using namespace ::com::sun::star; +using namespace ::drafts::com::sun::star::chart2; +using namespace ::rtl::math; + +TickInfo::TickInfo() +: fScaledTickValue( 0.0 ) +, fUnscaledTickValue( 0.0 ) +, nScreenTickValue( 0 ) +, bPaintIt( true ) +, xTextShape( NULL ) +{ +} + +void TickInfo::updateUnscaledValue( const uno::Reference< XScaling >& xInverseScaling ) +{ + if( xInverseScaling.is() ) + this->fUnscaledTickValue = xInverseScaling->doScaling( this->fScaledTickValue ); + else + this->fUnscaledTickValue = this->fScaledTickValue; +} + +TickIter::TickIter( const uno::Sequence< uno::Sequence< double > >& rTicks + , const ExplicitIncrementData& rIncrement + , sal_Int32 nMinDepth, sal_Int32 nMaxDepth ) + : m_pSimpleTicks(&rTicks), m_pInfoTicks(NULL) + , m_rIncrement(rIncrement) + , m_nMinDepth(0), m_nMaxDepth(0) + , m_nTickCount(0), m_pnPositions(NULL) + , m_pnPreParentCount(NULL), m_pbIntervalFinished(NULL) + , m_nCurrentDepth(-1), m_nCurrentPos(-1), m_fCurrentValue( 0.0 ) +{ + initIter( nMinDepth, nMaxDepth ); +} + +TickIter::TickIter( ::std::vector< ::std::vector< TickInfo > >& rTicks + , const ExplicitIncrementData& rIncrement + , sal_Int32 nMinDepth, sal_Int32 nMaxDepth ) + : m_pSimpleTicks(NULL), m_pInfoTicks(&rTicks) + , m_rIncrement(rIncrement) + , m_nMinDepth(0), m_nMaxDepth(0) + , m_nTickCount(0), m_pnPositions(NULL) + , m_pnPreParentCount(NULL), m_pbIntervalFinished(NULL) + , m_nCurrentDepth(-1), m_nCurrentPos(-1), m_fCurrentValue( 0.0 ) +{ + initIter( nMinDepth, nMaxDepth ); +} + +void TickIter::initIter( sal_Int32 nMinDepth, sal_Int32 nMaxDepth ) +{ + m_nMaxDepth = nMaxDepth; + if(nMaxDepth<0 || m_nMaxDepth>_getMaxDepth()) + m_nMaxDepth=_getMaxDepth(); + + sal_Int32 nDepth = 0; + for( nDepth = 0; nDepth<=m_nMaxDepth ;nDepth++ ) + m_nTickCount += _getTickCount(nDepth); + + if(!m_nTickCount) + return; + + m_pnPositions = new sal_Int32[m_nMaxDepth+1]; + + m_pnPreParentCount = new sal_Int32[m_nMaxDepth+1]; + m_pbIntervalFinished = new bool[m_nMaxDepth+1]; + m_pnPreParentCount[0] = 0; + m_pbIntervalFinished[0] = false; + double fParentValue = _getTickValue(0,0); + for( nDepth = 1; nDepth<=m_nMaxDepth ;nDepth++ ) + { + m_pbIntervalFinished[nDepth] = false; + + sal_Int32 nPreParentCount = 0; + sal_Int32 nCount = _getTickCount(nDepth); + for(sal_Int32 nN = 0; nN<nCount; nN++) + { + if(_getTickValue(nDepth,nN) < fParentValue) + nPreParentCount++; + else + break; + } + m_pnPreParentCount[nDepth] = nPreParentCount; + if(nCount) + { + double fNextParentValue = _getTickValue(nDepth,0); + if( fNextParentValue < fParentValue ) + fParentValue = fNextParentValue; + } + } +} + +TickIter::~TickIter() +{ + delete[] m_pnPositions; + delete[] m_pnPreParentCount; + delete[] m_pbIntervalFinished; +} + +sal_Int32 TickIter::getStartDepth() const +{ + //find the depth of the first visible tickmark: + //it is the depth of the smallest value + sal_Int32 nReturnDepth=0; + double fMinValue = DBL_MAX; + for(sal_Int32 nDepth = 0; nDepth<=m_nMaxDepth ;nDepth++ ) + { + sal_Int32 nCount = _getTickCount(nDepth); + if( !nCount ) + continue; + double fThisValue = _getTickValue(nDepth,0); + if(fThisValue<fMinValue) + { + nReturnDepth = nDepth; + fMinValue = fThisValue; + } + } + return nReturnDepth; +} + +double* TickIter::firstValue() +{ + if( gotoFirst() ) + { + m_fCurrentValue = _getTickValue(m_nCurrentDepth, m_pnPositions[m_nCurrentDepth]); + return &m_fCurrentValue; + } + return NULL; +} + +TickInfo* TickIter::firstInfo() +{ + if( m_pInfoTicks && gotoFirst() ) + return &(*m_pInfoTicks)[m_nCurrentDepth][m_pnPositions[m_nCurrentDepth]]; + return NULL; +} + +sal_Int32 TickIter::getIntervalCount( sal_Int32 nDepth ) +{ + if(nDepth>m_rIncrement.SubIncrements.getLength() || nDepth<0) + return 0; + + if(!nDepth) + return m_nTickCount; + + return m_rIncrement.SubIncrements[nDepth-1].IntervalCount; +} + +bool TickIter::isAtLastPartTick() +{ + if(!m_nCurrentDepth) + return false; + sal_Int32 nIntervalCount = getIntervalCount( m_nCurrentDepth ); + if(!nIntervalCount || nIntervalCount == 1) + return true; + if( m_pbIntervalFinished[m_nCurrentDepth] ) + return false; + sal_Int32 nPos = m_pnPositions[m_nCurrentDepth]+1; + if(m_pnPreParentCount[m_nCurrentDepth]) + nPos += nIntervalCount-1 - m_pnPreParentCount[m_nCurrentDepth]; + bool bRet = nPos && nPos % (nIntervalCount-1) == 0; + if(!nPos && !m_pnPreParentCount[m_nCurrentDepth] + && m_pnPositions[m_nCurrentDepth-1]==-1 ) + bRet = true; + return bRet; +} + +bool TickIter::gotoFirst() +{ + if( m_nMaxDepth<0 ) + return false; + if( !m_nTickCount ) + return false; + + for(sal_Int32 nDepth = 0; nDepth<=m_nMaxDepth ;nDepth++ ) + m_pnPositions[nDepth] = -1; + + m_nCurrentPos = 0; + m_nCurrentDepth = getStartDepth(); + m_pnPositions[m_nCurrentDepth] = 0; + return true; +} + +bool TickIter::gotoNext() +{ + if( m_nCurrentPos < 0 ) + return false; + m_nCurrentPos++; + + if( m_nCurrentPos >= m_nTickCount ) + return false; + + if( m_nCurrentDepth==m_nMaxDepth && isAtLastPartTick() ) + { + do + { + m_pbIntervalFinished[m_nCurrentDepth] = true; + m_nCurrentDepth--; + } + while( m_nCurrentDepth && isAtLastPartTick() ); + } + else if( m_nCurrentDepth<m_nMaxDepth ) + { + do + { + m_nCurrentDepth++; + } + while( m_nCurrentDepth<m_nMaxDepth ); + } + m_pbIntervalFinished[m_nCurrentDepth] = false; + m_pnPositions[m_nCurrentDepth] = m_pnPositions[m_nCurrentDepth]+1; + return true; +} + +double* TickIter::nextValue() +{ + if( gotoNext() ) + { + m_fCurrentValue = _getTickValue(m_nCurrentDepth, m_pnPositions[m_nCurrentDepth]); + return &m_fCurrentValue; + } + return NULL; +} + +TickInfo* TickIter::nextInfo() +{ + if( m_pInfoTicks && gotoNext() ) + return &(*m_pInfoTicks)[m_nCurrentDepth][m_pnPositions[m_nCurrentDepth]]; + return NULL; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//static +double TickmarkHelper::getMinimumAtIncrement( double fMin, const ExplicitIncrementData& rIncrement ) +{ + //the returned value will be <= fMin and on a Major Tick given by rIncrement + if(rIncrement.Distance<=0.0) + return fMin; + + double fRet = rIncrement.BaseValue + + static_cast<sal_Int32>( + approxSub( fMin, rIncrement.BaseValue ) + / rIncrement.Distance) + *rIncrement.Distance; + + if( fRet > fMin ) + { + if( !approxEqual(fRet, fMin) ) + fRet -= rIncrement.Distance; + } + return fRet; +} +//static +double TickmarkHelper::getMaximumAtIncrement( double fMax, const ExplicitIncrementData& rIncrement ) +{ + //the returned value will be >= fMax and on a Major Tick given by rIncrement + if(rIncrement.Distance<=0.0) + return fMax; + + double fRet = rIncrement.BaseValue + + static_cast<sal_Int32>( + approxSub( fMax, rIncrement.BaseValue ) + / rIncrement.Distance) + *rIncrement.Distance; + + if( fRet < fMax ) + { + if( !approxEqual(fRet, fMax) ) + fRet += rIncrement.Distance; + } + return fRet; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +TickmarkHelper::TickmarkHelper( + const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement ) + : m_rScale( rScale ) + , m_rIncrement( rIncrement ) + , m_xInverseScaling(NULL) + , m_pfCurrentValues(NULL) +{ + //@todo: make sure that the scale is valid for the scaling + + m_pfCurrentValues = new double[getTickDepth()]; + + if( m_rScale.Scaling.is() ) + { + m_xInverseScaling = m_rScale.Scaling->getInverseScaling(); + DBG_ASSERT( m_xInverseScaling.is(), "each Scaling needs to return a inverse Scaling" ); + } + + double fMin = m_fScaledVisibleMin = m_rScale.Minimum; + if( m_xInverseScaling.is() ) + { + m_fScaledVisibleMin = m_rScale.Scaling->doScaling(m_fScaledVisibleMin); + if(m_rIncrement.PostEquidistant ) + fMin = m_fScaledVisibleMin; + } + + double fMax = m_fScaledVisibleMax = m_rScale.Maximum; + if( m_xInverseScaling.is() ) + { + m_fScaledVisibleMax = m_rScale.Scaling->doScaling(m_fScaledVisibleMax); + if(m_rIncrement.PostEquidistant ) + fMax = m_fScaledVisibleMax; + } + + //-- + m_fOuterMajorTickBorderMin = TickmarkHelper::getMinimumAtIncrement( fMin, m_rIncrement ); + m_fOuterMajorTickBorderMax = TickmarkHelper::getMaximumAtIncrement( fMax, m_rIncrement ); + //-- + + m_fOuterMajorTickBorderMin_Scaled = m_fOuterMajorTickBorderMin; + m_fOuterMajorTickBorderMax_Scaled = m_fOuterMajorTickBorderMax; + if(!m_rIncrement.PostEquidistant && m_xInverseScaling.is() ) + { + m_fOuterMajorTickBorderMin_Scaled = m_rScale.Scaling->doScaling(m_fOuterMajorTickBorderMin); + m_fOuterMajorTickBorderMax_Scaled = m_rScale.Scaling->doScaling(m_fOuterMajorTickBorderMax); + + //check validity of new range: m_fOuterMajorTickBorderMin <-> m_fOuterMajorTickBorderMax + //it is assumed here, that the original range in the given Scale is valid + if( !rtl::math::isFinite(m_fOuterMajorTickBorderMin_Scaled) ) + { + m_fOuterMajorTickBorderMin += m_rIncrement.Distance; + m_fOuterMajorTickBorderMin_Scaled = m_rScale.Scaling->doScaling(m_fOuterMajorTickBorderMin); + } + if( !rtl::math::isFinite(m_fOuterMajorTickBorderMax_Scaled) ) + { + m_fOuterMajorTickBorderMax -= m_rIncrement.Distance; + m_fOuterMajorTickBorderMax_Scaled = m_rScale.Scaling->doScaling(m_fOuterMajorTickBorderMax); + } + } +} + +TickmarkHelper::~TickmarkHelper() +{ + delete[] m_pfCurrentValues; +} + +sal_Int32 TickmarkHelper::getTickDepth() const +{ + return m_rIncrement.SubIncrements.getLength() + 1; +} + +sal_Int32 TickmarkHelper::getMaxTickCount( sal_Int32 nDepth ) const +{ + //return the maximum amount of ticks + //possibly open intervals at the two ends of the region are handled as if they were completely visible + //(this is necessary for calculating the sub ticks at the borders correctly) + + if( nDepth >= getTickDepth() ) + return 0; + if( m_fOuterMajorTickBorderMax < m_fOuterMajorTickBorderMin ) + return 0; + + sal_Int32 nIntervalCount; + if(m_rIncrement.PostEquidistant ) + nIntervalCount = static_cast<sal_Int32> + ( approxSub( m_fScaledVisibleMax, m_fScaledVisibleMin ) + / m_rIncrement.Distance ); + else + nIntervalCount = static_cast<sal_Int32> + ( approxSub( m_rScale.Maximum, m_rScale.Minimum ) + / m_rIncrement.Distance ); + nIntervalCount+=3; + for(sal_Int32 nN=0; nN<nDepth-1; nN++) + { + if( m_rIncrement.SubIncrements[nN].IntervalCount>1 ) + nIntervalCount *= m_rIncrement.SubIncrements[nN].IntervalCount; + } + + sal_Int32 nTickCount = nIntervalCount; + if(nDepth>0 && m_rIncrement.SubIncrements[nDepth-1].IntervalCount>1) + nTickCount = nIntervalCount * (m_rIncrement.SubIncrements[nDepth-1].IntervalCount-1); + + return nTickCount; +} + +double* TickmarkHelper::getMajorTick( sal_Int32 nTick ) const +{ + m_pfCurrentValues[0] = m_fOuterMajorTickBorderMin + nTick*m_rIncrement.Distance; + + if(m_pfCurrentValues[0]>m_fOuterMajorTickBorderMax) + return NULL; + if(m_pfCurrentValues[0]<m_fOuterMajorTickBorderMin) + return NULL; + + //return always the value after scaling + if(!m_rIncrement.PostEquidistant && m_xInverseScaling.is() ) + m_pfCurrentValues[0] = m_rScale.Scaling->doScaling( m_pfCurrentValues[0] ); + + return &m_pfCurrentValues[0]; +} + +double* TickmarkHelper::getMinorTick( sal_Int32 nTick, sal_Int32 nDepth + , double fStartParentTick, double fNextParentTick ) const +{ + //check validity of arguments + { + //DBG_ASSERT( fStartParentTick < fNextParentTick, "fStartParentTick >= fNextParentTick"); + if(fStartParentTick >= fNextParentTick) + return NULL; + if(nDepth>m_rIncrement.SubIncrements.getLength() || nDepth<=0) + return NULL; + + //subticks are only calculated if they are laying between parent ticks: + if(nTick<=0) + return NULL; + if(nTick>=m_rIncrement.SubIncrements[nDepth-1].IntervalCount) + return NULL; + } + + bool bPostEquidistant = m_rIncrement.SubIncrements[nDepth-1].PostEquidistant; + + double fAdaptedStartParent = fStartParentTick; + double fAdaptedNextParent = fNextParentTick; + + if( !bPostEquidistant && m_xInverseScaling.is() ) + { + fAdaptedStartParent = m_xInverseScaling->doScaling(fStartParentTick); + fAdaptedNextParent = m_xInverseScaling->doScaling(fNextParentTick); + } + + double fDistance = (fAdaptedNextParent - fAdaptedStartParent)/m_rIncrement.SubIncrements[nDepth-1].IntervalCount; + + m_pfCurrentValues[nDepth] = fAdaptedStartParent + nTick*fDistance; + double& fTest = m_pfCurrentValues[nDepth]; + + //return always the value after scaling + if(!bPostEquidistant && m_xInverseScaling.is() ) + m_pfCurrentValues[nDepth] = m_rScale.Scaling->doScaling( m_pfCurrentValues[nDepth] ); + + if( !isWithinOuterBorder( m_pfCurrentValues[nDepth] ) ) + return NULL; + + return &m_pfCurrentValues[nDepth]; +} + +bool TickmarkHelper::isWithinOuterBorder( double fScaledValue ) const +{ + if(fScaledValue>m_fOuterMajorTickBorderMax_Scaled) + return false; + if(fScaledValue<m_fOuterMajorTickBorderMin_Scaled) + return false; + + return true; +} + + +bool TickmarkHelper::isVisible( double fScaledValue ) const +{ + if(fScaledValue>m_fScaledVisibleMax) + return false; + if(fScaledValue<m_fScaledVisibleMin) + return false; + + return true; +} + +bool TickmarkHelper::isPostEquidistant( sal_Int32 nDepth ) const +{ + if( nDepth<0 || nDepth>m_rIncrement.SubIncrements.getLength() ) + { + DBG_ERROR("invalid depth for tickmark"); + return true; + } + + if( nDepth==0 ) + return m_rIncrement.PostEquidistant; + + return m_rIncrement.SubIncrements[nDepth-1].PostEquidistant; +} + +void TickmarkHelper::getAllTicks( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const +{ + uno::Sequence< uno::Sequence< double > > aAllTicks; + + //create point sequences for each tick depth + sal_Int32 nDepthCount = this->getTickDepth(); + sal_Int32 nMaxMajorTickCount = this->getMaxTickCount( 0 ); + + aAllTicks.realloc(nDepthCount); + aAllTicks[0].realloc(nMaxMajorTickCount); + + sal_Int32 nRealMajorTickCount = 0; + double* pValue = NULL; + for( sal_Int32 nMajorTick=0; nMajorTick<nMaxMajorTickCount; nMajorTick++ ) + { + pValue = this->getMajorTick( nMajorTick ); + if(!pValue) + continue; + aAllTicks[0][nRealMajorTickCount] = *pValue; + nRealMajorTickCount++; + } + if(!nRealMajorTickCount) + return; + aAllTicks[0].realloc(nRealMajorTickCount); + + if(nDepthCount>0) + this->addSubTicks( 1, aAllTicks ); + + //so far we have added all ticks between the outer major tick marks + //this was necessary to create sub ticks correctly + //now we reduce all ticks to the visible ones that lie between the real borders + sal_Int32 nDepth = 0; + for( nDepth = 0; nDepth < nDepthCount; nDepth++) + { + sal_Int32 nInvisibleAtLowerBorder = 0; + sal_Int32 nInvisibleAtUpperBorder = 0; + //we need only to check all ticks within the first major interval at each border + sal_Int32 nCheckCount = 1; + for(sal_Int32 nN=0; nN<nDepth; nN++) + { + if( m_rIncrement.SubIncrements[nN].IntervalCount>1 ) + nCheckCount *= m_rIncrement.SubIncrements[nN].IntervalCount; + } + uno::Sequence< double >& rTicks = aAllTicks[nDepth]; + sal_Int32 nCount = rTicks.getLength(); + //check lower border + for( sal_Int32 nTick=0; nTick<nCheckCount && nTick<nCount; nTick++) + { + if( !isVisible( rTicks[nTick] ) ) + nInvisibleAtLowerBorder++; + } + //check upper border + for( nTick=nCount-1; nTick>nCount-1-nCheckCount && nTick>=0; nTick--) + { + if( !isVisible( rTicks[nTick] ) ) + nInvisibleAtUpperBorder++; + } + //resize sequence + if( !nInvisibleAtLowerBorder && !nInvisibleAtUpperBorder) + continue; + if( !nInvisibleAtLowerBorder ) + rTicks.realloc(nCount-nInvisibleAtUpperBorder); + else + { + sal_Int32 nNewCount = nCount-nInvisibleAtUpperBorder-nInvisibleAtLowerBorder; + if(nNewCount<0) + nNewCount=0; + + uno::Sequence< double > aOldTicks(rTicks); + rTicks.realloc(nNewCount); + for(sal_Int32 nTick = 0; nTick<nNewCount; nTick++) + rTicks[nTick] = aOldTicks[nInvisibleAtLowerBorder+nTick]; + } + } + + //fill return value + rAllTickInfos.resize(aAllTicks.getLength()); + for( nDepth=0 ;nDepth<aAllTicks.getLength(); nDepth++ ) + { + sal_Int32 nCount = aAllTicks[nDepth].getLength(); + rAllTickInfos[nDepth].resize( nCount ); + for(sal_Int32 nN = 0; nN<nCount; nN++) + { + rAllTickInfos[nDepth][nN].fScaledTickValue = aAllTicks[nDepth][nN]; + } + } + + //----------------------------------------- + //get the transformed screen values for all tickmarks in aAllTickInfos + this->updateScreenValues( rAllTickInfos ); + + //----------------------------------------- + //'hide' tickmarks with identical screen values in aAllTickInfos + this->hideIdenticalScreenValues( rAllTickInfos ); +} + +void TickmarkHelper::addSubTicks( sal_Int32 nDepth, uno::Sequence< uno::Sequence< double > >& rParentTicks ) const +{ + TickIter aIter( rParentTicks, m_rIncrement, 0, nDepth-1 ); + double* pfNextParentTick = aIter.firstValue(); + if(!pfNextParentTick) + return; + double fLastParentTick = *pfNextParentTick; + pfNextParentTick = aIter.nextValue(); + if(!pfNextParentTick) + return; + + sal_Int32 nMaxSubTickCount = this->getMaxTickCount( nDepth ); + if(!nMaxSubTickCount) + return; + + uno::Sequence< double > aSubTicks(nMaxSubTickCount); + sal_Int32 nRealSubTickCount = 0; + sal_Int32 nIntervalCount = m_rIncrement.SubIncrements[nDepth-1].IntervalCount; + + double* pValue = NULL; + for(; pfNextParentTick; fLastParentTick=*pfNextParentTick, pfNextParentTick = aIter.nextValue()) + { + for( sal_Int32 nPartTick = 1; nPartTick<nIntervalCount; nPartTick++ ) + { + pValue = this->getMinorTick( nPartTick, nDepth + , fLastParentTick, *pfNextParentTick ); + if(!pValue) + continue; + + aSubTicks[nRealSubTickCount] = *pValue; + nRealSubTickCount++; + } + } + + aSubTicks.realloc(nRealSubTickCount); + rParentTicks[nDepth] = aSubTicks; + if(m_rIncrement.SubIncrements.getLength()>nDepth) + addSubTicks( nDepth+1, rParentTicks ); +} + +//----------------------------------------------------------------------------- +// ___TickmarkHelper_3D___ +//----------------------------------------------------------------------------- +TickmarkHelper_2D::TickmarkHelper_2D( + const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement + , double fStrech_SceneToScreen, double fOffset_SceneToScreen ) + : TickmarkHelper( rScale, rIncrement ) + , m_fStrech_LogicToScreen(1.0) + , m_fOffset_LogicToScreen(0.0) +{ + double fWidthY = m_fScaledVisibleMax - m_fScaledVisibleMin; + m_fStrech_LogicToScreen = FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY * fStrech_SceneToScreen; + m_fOffset_LogicToScreen = -m_fScaledVisibleMin*m_fStrech_LogicToScreen + fOffset_SceneToScreen; +} + +TickmarkHelper_2D::~TickmarkHelper_2D() +{ +} + +sal_Int32 TickmarkHelper_2D::transformScaledLogicTickToScreen( double fValue ) const +{ + sal_Int32 nRet = static_cast<sal_Int32>( + fValue*m_fStrech_LogicToScreen + m_fOffset_LogicToScreen); + return nRet; +} + +//static +sal_Int32 TickmarkHelper_2D::getTickScreenDistance( TickIter& rIter ) +{ + //return the positive distance between the two first tickmarks in screen values + //if there are less than two tickmarks -1 is returned + + const TickInfo* pFirstTickInfo = rIter.firstInfo(); + const TickInfo* pSecondTickInfo = rIter.nextInfo(); + if(!pSecondTickInfo || !pFirstTickInfo) + return -1; + + sal_Int32 nRet = pSecondTickInfo->nScreenTickValue - pFirstTickInfo->nScreenTickValue; + if(nRet<0) + nRet *= -1; + return nRet; +} + +sal_Int32 TickmarkHelper_2D::getScreenValueForMinimum() const +{ + //return the screen value at the end of the axis where the scale has its minimum + //(lower end of axis line) + return this->transformScaledLogicTickToScreen( + m_fScaledVisibleMin ); +} + +sal_Int32 TickmarkHelper_2D::getScreenValueForMaximum() const +{ + //return the screen value at the end of the axis where the scale has its maximum + //(upper end of axis line) + return this->transformScaledLogicTickToScreen( + m_fScaledVisibleMax ); +} + +void TickmarkHelper_2D::updateScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const +{ + //get the transformed screen values for all tickmarks in rAllTickInfos + ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = rAllTickInfos.begin(); + const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = rAllTickInfos.end(); + for( ; aDepthIter != aDepthEnd; aDepthIter++ ) + { + ::std::vector< TickInfo >::iterator aTickIter = (*aDepthIter).begin(); + const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end(); + for( ; aTickIter != aTickEnd; aTickIter++ ) + { + TickInfo& rTickInfo = (*aTickIter); + rTickInfo.nScreenTickValue = + this->transformScaledLogicTickToScreen( + rTickInfo.fScaledTickValue ); + } + } +} + +//'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 = pTickInfo->nScreenTickValue != pPreviousTickInfo->nScreenTickValue; + pPreviousTickInfo = pTickInfo; + } +} +//----------------------------------------------------------------------------- +// ___TickmarkHelper_3D___ +//----------------------------------------------------------------------------- +TickmarkHelper_3D::TickmarkHelper_3D( + const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement ) + : TickmarkHelper( rScale, rIncrement ) +{ +} + +TickmarkHelper_3D::~TickmarkHelper_3D() +{ +} + +//............................................................................. +} //namespace chart +//............................................................................. diff --git a/chart2/source/view/axes/TickmarkHelper.hxx b/chart2/source/view/axes/TickmarkHelper.hxx new file mode 100644 index 000000000000..1462cc8dcb5c --- /dev/null +++ b/chart2/source/view/axes/TickmarkHelper.hxx @@ -0,0 +1,265 @@ +/************************************************************************* + * + * $RCSfile: TickmarkHelper.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2003 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _CHART2_TICKMARKHELPER_HXX +#define _CHART2_TICKMARKHELPER_HXX + +#include <vector> + +#ifndef _DRAFTS_COM_SUN_STAR_CHART2_EXPLICITINCREMENTDATA_HPP_ +#include <drafts/com/sun/star/chart2/ExplicitIncrementData.hpp> +#endif +#ifndef _DRAFTS_COM_SUN_STAR_CHART2_EXPLICITSCALEDATA_HPP_ +#include <drafts/com/sun/star/chart2/ExplicitScaleData.hpp> +#endif + +#ifndef _COM_SUN_STAR_DRAWING_XSHAPE_HPP_ +#include <com/sun/star/drawing/XShape.hpp> +#endif +#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_ +#include <com/sun/star/uno/Sequence.h> +#endif + +//............................................................................. +namespace chart +{ +//............................................................................. + +//----------------------------------------------------------------------------- +/** +*/ + +struct TickInfo +{ + double fScaledTickValue; + double fUnscaledTickValue; + + sal_Int32 nScreenTickValue; + + bool bPaintIt; + + ::com::sun::star::uno::Reference< + ::com::sun::star::drawing::XShape > xTextShape; + +//methods: + TickInfo(); + void updateUnscaledValue( const ::com::sun::star::uno::Reference< + ::drafts::com::sun::star::chart2::XScaling >& xInverseScaling ); +}; + +class TickIter +{ +public: + TickIter( const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Sequence< double > >& rTicks + , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement + , sal_Int32 nMinDepth=0, sal_Int32 nMaxDepth=-1 ); + TickIter( ::std::vector< ::std::vector< TickInfo > >& rTickInfos + , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement + , sal_Int32 nMinDepth=0, sal_Int32 nMaxDepth=-1 ); + virtual ~TickIter(); + + double* firstValue(); + double* nextValue(); + + TickInfo* firstInfo(); + TickInfo* nextInfo(); + + sal_Int32 getCurrentDepth() const { return m_nCurrentDepth; } + +private: //methods + sal_Int32 getIntervalCount( sal_Int32 nDepth ); + bool isAtLastPartTick(); + + void initIter( sal_Int32 nMinDepth, sal_Int32 nMaxDepth ); + sal_Int32 getStartDepth() const; + + bool gotoFirst(); + bool gotoNext(); + + + double _getTickValue(sal_Int32 nDepth, sal_Int32 nIndex) const + { + if(m_pSimpleTicks) + return (*m_pSimpleTicks)[nDepth][nIndex]; + else + return (((*m_pInfoTicks)[nDepth])[nIndex]).fScaledTickValue; + } + sal_Int32 _getTickCount( sal_Int32 nDepth ) const + { + if(m_pSimpleTicks) + return (*m_pSimpleTicks)[nDepth].getLength(); + else + return (*m_pInfoTicks)[nDepth].size(); + } + sal_Int32 _getMaxDepth() const + { + if(m_pSimpleTicks) + return (*m_pSimpleTicks).getLength()-1; + else + return (*m_pInfoTicks).size()-1; + } + +private: //member + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Sequence< double > >* m_pSimpleTicks; + ::std::vector< ::std::vector< TickInfo > >* m_pInfoTicks; + const ::drafts::com::sun::star::chart2::ExplicitIncrementData& m_rIncrement; + //iteration from m_nMinDepth to m_nMaxDepth + sal_Int32 m_nMinDepth; + sal_Int32 m_nMaxDepth; + sal_Int32 m_nTickCount; + sal_Int32* m_pnPositions; //current positions in the different sequences + sal_Int32* m_pnPreParentCount; //the tickmarks do not start with a major tick always, + //the PreParentCount states for each depth how many subtickmarks are available in front of the first parent tickmark + bool* m_pbIntervalFinished; + sal_Int32 m_nCurrentDepth; + sal_Int32 m_nCurrentPos; + double m_fCurrentValue; +}; + +class TickmarkHelper +{ +public: + TickmarkHelper( + const ::drafts::com::sun::star::chart2::ExplicitScaleData& rScale + , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement ); + virtual ~TickmarkHelper(); + + void getAllTicks( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const; + bool isPostEquidistant( sal_Int32 nDepth ) const; + + // + static double getMinimumAtIncrement( double fMin, const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement ); + static double getMaximumAtIncrement( double fMax, const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement ); + +protected: //methods + void addSubTicks( sal_Int32 nDepth, + ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Sequence< double > >& rParentTicks ) const; + double* getMajorTick( sal_Int32 nTick ) const; + double* getMinorTick( sal_Int32 nTick, sal_Int32 nDepth + , double fStartParentTick, double fNextParentTick ) const; + sal_Int32 getMaxTickCount( sal_Int32 nDepth = 0 ) const; + sal_Int32 getTickDepth() const; + bool isVisible( double fValue ) const; + 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 + const ::drafts::com::sun::star::chart2::ExplicitScaleData& m_rScale; + const ::drafts::com::sun::star::chart2::ExplicitIncrementData& m_rIncrement; + + ::com::sun::star::uno::Reference< ::drafts::com::sun::star::chart2::XScaling > + m_xInverseScaling; + double* m_pfCurrentValues; + //major-tick positions that may lay outside the visible range but complete partly visible intervals at the borders + double m_fOuterMajorTickBorderMin; + double m_fOuterMajorTickBorderMax; + double m_fOuterMajorTickBorderMin_Scaled; + double m_fOuterMajorTickBorderMax_Scaled; + + //minimum and maximum of the visible range after scaling + double m_fScaledVisibleMin; + double m_fScaledVisibleMax; +}; + +class TickmarkHelper_2D : public TickmarkHelper +{ +public: + TickmarkHelper_2D( + const ::drafts::com::sun::star::chart2::ExplicitScaleData& rScale + , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement + , double fStrech_SceneToScreen, double fOffset_SceneToScreen ); + virtual ~TickmarkHelper_2D(); + + static sal_Int32 getTickScreenDistance( TickIter& rIter ); + + //methods more for axis line + sal_Int32 getScreenValueForMinimum() const; + sal_Int32 getScreenValueForMaximum() const; + +protected: //methods + virtual void updateScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const; + virtual void hideIdenticalScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const; + + sal_Int32 transformScaledLogicTickToScreen( double fValue ) const; + +private: //member + double m_fStrech_LogicToScreen; + double m_fOffset_LogicToScreen; +}; + +class TickmarkHelper_3D : public TickmarkHelper +{ +public: + TickmarkHelper_3D( + const ::drafts::com::sun::star::chart2::ExplicitScaleData& rScale + , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement ); + virtual ~TickmarkHelper_3D(); + +}; + +//............................................................................. +} //namespace chart +//............................................................................. +#endif diff --git a/chart2/source/view/axes/VAxisProperties.cxx b/chart2/source/view/axes/VAxisProperties.cxx new file mode 100644 index 000000000000..b94493b16524 --- /dev/null +++ b/chart2/source/view/axes/VAxisProperties.cxx @@ -0,0 +1,468 @@ +/************************************************************************* + * + * $RCSfile: VAxisProperties.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2003 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include "VAxisProperties.hxx" +#include "macros.hxx" +#include "ViewDefines.hxx" +#include "CommonConverters.hxx" + +#ifndef _TOOLS_COLOR_HXX +#include <tools/color.hxx> +#endif + +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif +#ifndef _COM_SUN_STAR_CHART_CHARTAXISARRANGEORDERTYPE_HPP_ +#include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp> +#endif +#ifndef _COM_SUN_STAR_DRAWING_LINESTYLE_HPP_ +#include <com/sun/star/drawing/LineStyle.hpp> +#endif +#ifndef _COM_SUN_STAR_TEXT_WRITINGMODE2_HPP_ +#include <com/sun/star/text/WritingMode2.hpp> +#endif + +//............................................................................. +namespace chart +{ +//............................................................................. +using namespace ::com::sun::star; +using namespace ::drafts::com::sun::star::chart2; + +sal_Int32 AxisProperties::calcTickLengthForDepth(sal_Int32 nDepth,sal_Int32 nTickmarkStyle) const +{ + sal_Int32 nWidth = AXIS2D_TICKLENGTH; //@maybefuturetodo this length could be offered by the model + double fPercent = 1.0; + switch(nDepth) + { + case 0: + fPercent = 1.0; + break; + case 1: + fPercent = 0.75;//percentage like in the old chart + break; + case 2: + fPercent = 0.5; + break; + default: + fPercent = 0.3; + break; + } + if(nTickmarkStyle==3)//inner and outer tickmarks + fPercent*=2.0; + return static_cast<sal_Int32>(nWidth*fPercent); +} + +sal_Int32 getTickOffset(sal_Int32 nLength,sal_Int32 nTickmarkStyle) +{ + double fPercent = 0.0; //0<=fPercent<=1 + //0.0: completly inner + //1.0: completly outer + //0.5: half and half + + /* + nTickmarkStyle: + 1: inner tickmarks + 2: outer tickmarks + 3: inner and outer tickmarks + */ + switch(nTickmarkStyle) + { + case 1: + fPercent = 0.0; + break; + case 2: + fPercent = 1.0; + break; + default: + fPercent = 0.5; + break; + } + return static_cast<sal_Int32>(fPercent*nLength); +} + +LineProperties AxisProperties::makeLinePropertiesForDepth( sal_Int32 nDepth ) const +{ + //@todo get this from somewhere; maybe for each subincrement + //so far the model does not offer different settings for each tick depth + return m_aLineProperties; +} + +TickmarkProperties AxisProperties::makeTickmarkProperties( + sal_Int32 nDepth ) const +{ + /* + nTickmarkStyle: + 1: inner tickmarks + 2: outer tickmarks + 3: inner and outer tickmarks + */ + sal_Int32 nTickmarkStyle = 1; + if(nDepth==0) + { + nTickmarkStyle = m_nMajorTickmarks; + if(!nTickmarkStyle) + { + //create major tickmarks as if they were minor tickmarks + nDepth = 1; + nTickmarkStyle = m_nMinorTickmarks; + } + } + else if( nDepth==1) + { + nTickmarkStyle = m_nMinorTickmarks; + } + + TickmarkProperties aTickmarkProperties; + aTickmarkProperties.Length = this->calcTickLengthForDepth(nDepth,nTickmarkStyle); + + sal_Int32 nSign = m_bIsLeftOrBottomAxis ? 1 : -1; + if(m_bIsYAxis) + nSign *= -1; + aTickmarkProperties.RelativePos = nSign*getTickOffset(aTickmarkProperties.Length,nTickmarkStyle); + aTickmarkProperties.Length *= -nSign; + aTickmarkProperties.aLineProperties = this->makeLinePropertiesForDepth( nDepth ); + return aTickmarkProperties; +} + +//-------------------------------------------------------------------------- + +AxisProperties::AxisProperties() + : m_xAxisModel(NULL) + , m_bIsYAxis(true) + , m_bIsLeftOrBottomAxis(true) + , m_pfMainLinePositionAtOtherAxis(NULL) + , m_pfExrtaLinePositionAtOtherAxis(NULL) + /* + , m_nOrthogonalAxisScreenPosition(0) + , m_nOrthogonalAxisExtraLineScreenPosition(0) + */ + , m_eRelativeLabelPosition(LEFTORBOTTOM_OF_AXIS) + , m_nMajorTickmarks(1) + , m_nMinorTickmarks(1) + , m_aTickmarkPropertiesList() + , m_aLineProperties() + , m_bTESTTEST_HorizontalAdjustmentIsLeft(true) +{ +} + +AxisProperties::AxisProperties( const AxisProperties& rAxisProperties ) + : m_xAxisModel( rAxisProperties.m_xAxisModel ) + , m_bIsYAxis( rAxisProperties.m_bIsYAxis ) + , m_bIsLeftOrBottomAxis( rAxisProperties.m_bIsLeftOrBottomAxis ) + , m_pfMainLinePositionAtOtherAxis( NULL ) + , m_pfExrtaLinePositionAtOtherAxis( NULL ) + , m_eRelativeLabelPosition( rAxisProperties.m_eRelativeLabelPosition ) + , m_nMajorTickmarks( rAxisProperties.m_nMajorTickmarks ) + , m_nMinorTickmarks( rAxisProperties.m_nMinorTickmarks ) + , m_aTickmarkPropertiesList( rAxisProperties.m_aTickmarkPropertiesList ) + , m_aLineProperties( rAxisProperties.m_aLineProperties ) + , m_bTESTTEST_HorizontalAdjustmentIsLeft( rAxisProperties.m_bTESTTEST_HorizontalAdjustmentIsLeft ) +{ + if( rAxisProperties.m_pfMainLinePositionAtOtherAxis ) + m_pfMainLinePositionAtOtherAxis = new double(*rAxisProperties.m_pfMainLinePositionAtOtherAxis); + if( rAxisProperties.m_pfExrtaLinePositionAtOtherAxis ) + m_pfExrtaLinePositionAtOtherAxis = new double (*rAxisProperties.m_pfExrtaLinePositionAtOtherAxis); +} + +AxisProperties::~AxisProperties() +{ + delete m_pfMainLinePositionAtOtherAxis; + delete m_pfExrtaLinePositionAtOtherAxis; +} + +void AxisProperties::init() +{ + if( !m_xAxisModel.is() ) + return; + sal_Int32 nDimension = m_xAxisModel->getRepresentedDimension(); + m_bIsYAxis = (nDimension==1); + + //init LineProperties + m_aLineProperties.initFromPropertySet( uno::Reference<beans::XPropertySet>::query( m_xAxisModel ) ); + + //init TickmarkProperties + uno::Reference< beans::XPropertySet > xProp = + uno::Reference<beans::XPropertySet>::query( this->m_xAxisModel ); + if(xProp.is()) + { + try + { + xProp->getPropertyValue( C2U( "MajorTickmarks" ) ) >>= m_nMajorTickmarks; + xProp->getPropertyValue( C2U( "MinorTickmarks" ) ) >>= m_nMinorTickmarks; + + sal_Int32 nMaxDepth = 0; + if(m_nMinorTickmarks!=0) + nMaxDepth=2; + else if(m_nMajorTickmarks!=0) + nMaxDepth=1; + + this->m_aTickmarkPropertiesList.clear(); + for( sal_Int32 nDepth=0; nDepth<nMaxDepth; nDepth++ ) + { + TickmarkProperties aTickmarkProperties = this->makeTickmarkProperties( nDepth ); + this->m_aTickmarkPropertiesList.push_back( aTickmarkProperties ); + } + } + catch( uno::Exception& e ) + { + e; + } + } +} + +sal_Int32 getAxisScreenPosition( double fCrossOtherAxis + , const PlottingPositionHelper& rPosHelper, bool bIsYAxis ) +{ + double fX = bIsYAxis ? fCrossOtherAxis : rPosHelper.getLogicMinX(); + double fY = bIsYAxis ? rPosHelper.getLogicMinY() : fCrossOtherAxis; + + rPosHelper.clipLogicValues( &fX,&fY,0 ); + rPosHelper.doLogicScaling( &fX,&fY,0 ); + drawing::Position3D aPos( fX, fY, 0); + + uno::Reference< XTransformation > xTransformation = + rPosHelper.getTransformationLogicToScene(); + uno::Sequence< double > aSeq = + xTransformation->transform( Position3DToSequence(aPos) ); + + return static_cast<sal_Int32>( + bIsYAxis ? aSeq[0] : aSeq[1] ); +} + + + +sal_Int32 AxisProperties::getMainLineScreenPosition( + const PlottingPositionHelper& rPosHelper ) const +{ + double fMin = m_bIsYAxis ? rPosHelper.getLogicMinX() : rPosHelper.getLogicMinY(); + double fMax = m_bIsYAxis ? rPosHelper.getLogicMaxX() : rPosHelper.getLogicMaxY(); + + double fCrossOtherAxis; + if(m_pfMainLinePositionAtOtherAxis) + fCrossOtherAxis = *m_pfMainLinePositionAtOtherAxis; + else + fCrossOtherAxis = m_bIsLeftOrBottomAxis ? fMin : fMax; + sal_Int32 nRet = getAxisScreenPosition( fCrossOtherAxis, rPosHelper, m_bIsYAxis ); + return nRet; +} + +bool AxisProperties::getExtraLineScreenPosition( + sal_Int32& rnExtraLineScreenPosition, const PlottingPositionHelper& rPosHelper ) const +{ + if( !m_pfExrtaLinePositionAtOtherAxis ) + return false; + + double fMin = m_bIsYAxis ? rPosHelper.getLogicMinX() : rPosHelper.getLogicMinY(); + double fMax = m_bIsYAxis ? rPosHelper.getLogicMaxX() : rPosHelper.getLogicMaxY(); + if( *m_pfExrtaLinePositionAtOtherAxis <= fMin + || *m_pfExrtaLinePositionAtOtherAxis >= fMax ) + return false; + rnExtraLineScreenPosition = getAxisScreenPosition( + *m_pfExrtaLinePositionAtOtherAxis, rPosHelper, m_bIsYAxis ); + return true; +} + +//----------------------------------------------------------------------------- + +AxisLabelProperties::AxisLabelProperties() + : aNumberFormat() + , bDisplayLabels( true ) + , eStaggering( SIDE_BY_SIDE ) + , bLineBreakAllowed( true ) + , bOverlapAllowed( false ) + , bStackCharacters( false ) + , fRotationAngleDegree( 0.0 ) + , nRhythm( 1 ) + , bRhythmIsFix(false) +{ + /* + aLocale.Language = C2U( "en" ); + aLocale.Country = C2U( "US" ); + + //aLocale.Language = C2U( "ar" ); + //aLocale.Country = C2U( "IR" ); + + //aLocale.Language = C2U( "ja" ); + //aLocale.Country = C2U( "JP" ); + */ +} + +void AxisLabelProperties::init( const uno::Reference< XAxis >& xAxisModel ) +{ + uno::Reference< beans::XPropertySet > xProp = + uno::Reference<beans::XPropertySet>::query( xAxisModel ); + if(xProp.is()) + { + try + { + if( !( xProp->getPropertyValue( C2U( "NumberFormat" ) ) >>= this->aNumberFormat ) ) + { + //@todo get number format from calc + } + + xProp->getPropertyValue( C2U( "DisplayLabels" ) ) >>= this->bDisplayLabels; + xProp->getPropertyValue( C2U( "TextBreak" ) ) >>= this->bLineBreakAllowed; + xProp->getPropertyValue( C2U( "TextOverlap" ) ) >>= this->bOverlapAllowed; + xProp->getPropertyValue( C2U( "StackCharacters" ) ) >>= this->bStackCharacters; + xProp->getPropertyValue( C2U( "TextRotation" ) ) >>= this->fRotationAngleDegree; + + ::com::sun::star::chart::ChartAxisArrangeOrderType eArrangeOrder; + xProp->getPropertyValue( C2U( "ArrangeOrder" ) ) >>= eArrangeOrder; + switch(eArrangeOrder) + { + case ::com::sun::star::chart::ChartAxisArrangeOrderType_SIDE_BY_SIDE: + this->eStaggering = SIDE_BY_SIDE; + break; + case ::com::sun::star::chart::ChartAxisArrangeOrderType_STAGGER_EVEN: + this->eStaggering = STAGGER_EVEN; + break; + case ::com::sun::star::chart::ChartAxisArrangeOrderType_STAGGER_ODD: + this->eStaggering = STAGGER_ODD; + break; + default: + this->eStaggering = STAGGER_AUTO; + break; + } + } + catch( uno::Exception& e ) + { + e; + } + } +} + +/* +sal_Int16 getSwappedWritingMode( sal_Int16 nWritingMode ) +{ + //LR_TB == LT + //RL_TB == RT (Arabic, Hebrew) + //TB_RL == TR (Japanese, Chinese, Korean) + // ?? TL (Mongolian) see also text::WritingMode2 + + switch(nWritingMode) + { + case text::WritingMode2::RL_TB: + return text::WritingMode2::TB_RL; + case text::WritingMode2::TB_RL: + return text::WritingMode2::RL_TB; + case text::WritingMode2::LR_TB: + return text::WritingMode2::TB_LR; + default: + return text::WritingMode2::LR_TB; + } +} +*/ + +sal_Bool AxisLabelProperties::getIsStaggered() const +{ + if( STAGGER_ODD == eStaggering || STAGGER_EVEN == eStaggering ) + return sal_True; + return sal_False; +} + +//------------------------ + +drawing::TextVerticalAdjust AxisProperties::getVerticalAdjustment() const +{ + drawing::TextVerticalAdjust aRet = + !m_bIsYAxis && !m_bIsLeftOrBottomAxis + ? drawing::TextVerticalAdjust_BOTTOM + : drawing::TextVerticalAdjust_TOP; + return aRet; +} + +sal_Int16 AxisProperties::getWritingMode()const +{ + //@todo get this dependent on the locale ... + sal_Int16 nWritingMode( text::WritingMode2::LR_TB ); + return nWritingMode; +} + +drawing::TextHorizontalAdjust AxisProperties::getHorizontalAdjustment() const +{ + return m_bTESTTEST_HorizontalAdjustmentIsLeft + ? drawing::TextHorizontalAdjust_LEFT + : drawing::TextHorizontalAdjust_RIGHT; +// + + bool bIsYAxis = m_bIsYAxis; + bool bIsLeftOrBottomAxis = m_bIsLeftOrBottomAxis; + sal_Int16 nWritingMode = getWritingMode(); + + switch( nWritingMode ) + { + case text::WritingMode2::RL_TB: + case text::WritingMode2::TB_RL: + return bIsYAxis && !bIsLeftOrBottomAxis + ? drawing::TextHorizontalAdjust_LEFT + : drawing::TextHorizontalAdjust_RIGHT; + case text::WritingMode2::TB_LR: + default: + return bIsYAxis && bIsLeftOrBottomAxis + ? drawing::TextHorizontalAdjust_RIGHT + : drawing::TextHorizontalAdjust_LEFT; + } +} + +//............................................................................. +} //namespace chart +//............................................................................. diff --git a/chart2/source/view/axes/VCoordinateSystem.cxx b/chart2/source/view/axes/VCoordinateSystem.cxx new file mode 100644 index 000000000000..dc9c9e08cc6d --- /dev/null +++ b/chart2/source/view/axes/VCoordinateSystem.cxx @@ -0,0 +1,226 @@ +/************************************************************************* + * + * $RCSfile: VCoordinateSystem.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2003 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include "VCoordinateSystem.hxx" +#include "ScaleAutomatism.hxx" +#include "VSeriesPlotter.hxx" +#include "VGrid.hxx" + +//............................................................................. +namespace chart +{ +//............................................................................. +using namespace ::com::sun::star; +using namespace ::drafts::com::sun::star::chart2; + +VCoordinateSystem::VCoordinateSystem( const uno::Reference< XBoundedCoordinateSystem >& xCooSys ) + : m_xCooSysModel(xCooSys) + , m_xAxis0(NULL) + , m_xAxis1(NULL) + , m_xAxis2(NULL) + , m_xGridList0() + , m_xGridList1() + , m_xGridList2() + , m_aExplicitScales(3) + , m_aExplicitIncrements(3) +{ +} +VCoordinateSystem::~VCoordinateSystem() +{ + +} + +void VCoordinateSystem::setOrigin( double* fCoordinateOrigin ) +{ + m_fCoordinateOrigin[0]=fCoordinateOrigin[0]; + m_fCoordinateOrigin[1]=fCoordinateOrigin[1]; + m_fCoordinateOrigin[2]=fCoordinateOrigin[2]; +} + +uno::Reference< XBoundedCoordinateSystem > VCoordinateSystem::getModel() const +{ + return m_xCooSysModel; +} + +void VCoordinateSystem::addAxis( const uno::Reference< XAxis >& xAxis ) +{ + if(!xAxis.is()) + return; + sal_Int32 nDim = xAxis->getRepresentedDimension(); + if(0==nDim) + m_xAxis0 = xAxis; + else if(1==nDim) + m_xAxis1 = xAxis; + else if(2==nDim) + m_xAxis2 = xAxis; +} + +uno::Sequence< uno::Reference< XGrid > >& VCoordinateSystem::getGridListByDimension( sal_Int32 nDim ) +{ + if( 0==nDim ) + return m_xGridList0; + if( 1==nDim ) + return m_xGridList1; + return m_xGridList2; +} + +void VCoordinateSystem::addGrid( const uno::Reference< XGrid >& xGrid ) +{ + if(!xGrid.is()) + return; + sal_Int32 nDim = xGrid->getRepresentedDimension(); + uno::Sequence< uno::Reference< XGrid > >& rGridList + = getGridListByDimension( nDim ); + + rGridList.realloc(rGridList.getLength()+1); + rGridList[rGridList.getLength()-1] = xGrid; +} + +void VCoordinateSystem::createGridShapes( + const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory + , const uno::Reference< drawing::XShapes >& xTarget + , const drawing::HomogenMatrix& rHM_SceneToScreen ) +{ + sal_Int32 nDimensionCount = m_xCooSysModel->getDimension(); + for( sal_Int32 nDim=0; nDim<3; nDim++) + { + uno::Sequence< uno::Reference< XGrid > >& rGridList + = getGridListByDimension( nDim ); + for( sal_Int32 nN=0; nN<rGridList.getLength(); nN++ ) + { + VGrid aGrid(rGridList[nN],nDimensionCount); + aGrid.setMeterData( m_aExplicitScales[nDim], m_aExplicitIncrements[nDim] ); + + aGrid.init(xTarget,xTarget,xShapeFactory); + if(2==nDimensionCount) + aGrid.setTransformationSceneToScreen( rHM_SceneToScreen ); + aGrid.setScales( m_aExplicitScales ); + aGrid.createShapes(); + } + } +} + +uno::Reference< XAxis > VCoordinateSystem::getAxisByDimension( sal_Int32 nDim ) const +{ + uno::Reference< XAxis > xAxis(NULL); + if(0==nDim) + xAxis = m_xAxis0; + else if(1==nDim) + xAxis = m_xAxis1; + else if(2==nDim) + xAxis = m_xAxis2; + return xAxis; +} + +void setExplicitScaleToDefault( ExplicitScaleData& rExplicitScale ) +{ + rExplicitScale.Minimum = 0.0; + rExplicitScale.Maximum = 1.0; + rExplicitScale.Orientation = AxisOrientation_MATHEMATICAL; + //rExplicitScale.Scaling = ; + //rExplicitScale.Breaks = ; +} + +void VCoordinateSystem::doAutoScale( MinimumAndMaximumSupplier* pMinMaxSupplier ) +{ + for( sal_Int32 nDim = 0; nDim < 2; nDim++ ) + { + if(nDim < 0 || nDim > 2 ) + return; + + uno::Reference< XScale > xScale( + m_xCooSysModel->getScaleByDimension( nDim ), + uno::UNO_QUERY ); + if( ! xScale.is() ) + return; + ScaleAutomatism aScaleAutomatism( xScale->getScaleData() ); + uno::Reference< XAxis > xAxis( this->getAxisByDimension(nDim) ); + if(xAxis.is()) + { + uno::Reference< XIncrement > xInc( xAxis->getIncrement() ); + if( xInc.is() ) + { + aScaleAutomatism.m_aSourceIncrement = xInc->getIncrementData(); + aScaleAutomatism.m_aSourceSubIncrementList = xInc->getSubIncrements(); + } + } + if(0==nDim) + { + aScaleAutomatism.m_fValueMinimum = pMinMaxSupplier->getMinimumX(); + aScaleAutomatism.m_fValueMaximum = pMinMaxSupplier->getMaximumX(); + } + else if(1==nDim) + { + const ExplicitScaleData& rScale = m_aExplicitScales[0]; + //@todo iterate through all xSlots which belong to coordinate system dimension in this plotter + //and iterate through all plotter for this coordinate system dimension + sal_Int32 nXSlotIndex = 0; + aScaleAutomatism.m_fValueMinimum = pMinMaxSupplier->getMinimumYInRange(rScale.Minimum,rScale.Maximum); + aScaleAutomatism.m_fValueMaximum = pMinMaxSupplier->getMaximumYInRange(rScale.Minimum,rScale.Maximum); + } + aScaleAutomatism.calculateExplicitScaleAndIncrement( + m_aExplicitScales[nDim], m_aExplicitIncrements[nDim] ); + } + setExplicitScaleToDefault(m_aExplicitScales[2]); +} + +//............................................................................. +} //namespace chart +//............................................................................. diff --git a/chart2/source/view/axes/makefile.mk b/chart2/source/view/axes/makefile.mk new file mode 100644 index 000000000000..dd0fac9cff24 --- /dev/null +++ b/chart2/source/view/axes/makefile.mk @@ -0,0 +1,91 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ= ..$/..$/.. +PRJINC= $(PRJ)$/source +PRJNAME= chart2 +TARGET= chvaxes + +ENABLE_EXCEPTIONS= TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE: settings.mk +#.IF "$(GUI)" == "WNT" +#CFLAGS+=-GR +#.ENDIF + +# --- export library ------------------------------------------------- + +#object files to build and link together to lib $(SLB)$/$(TARGET).lib +SLOFILES = \ + $(SLO)$/VMeterBase.obj \ + $(SLO)$/TickmarkHelper.obj \ + $(SLO)$/ScaleAutomatism.obj \ + $(SLO)$/VCoordinateSystem.obj \ + $(SLO)$/VAxisProperties.obj \ + $(SLO)$/VAxis.obj \ + $(SLO)$/VGrid.obj + +# --- Targets ----------------------------------------------------------------- + +.INCLUDE: target.mk |