Files
libreoffice/chart2/source/view/main/ChartView.cxx

875 lines
36 KiB
C++
Raw Normal View History

2003-10-06 08:58:36 +00:00
/*************************************************************************
*
* $RCSfile: ChartView.cxx,v $
*
2003-12-17 15:43:22 +00:00
* $Revision: 1.28 $
2003-10-06 08:58:36 +00:00
*
2003-12-17 15:43:22 +00:00
* last change: $Author: bm $ $Date: 2003-12-17 16:43:18 $
2003-10-06 08:58:36 +00:00
*
* 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 "ChartViewImpl.hxx"
#include "PlottingPositionHelper.hxx"
#include "ViewDefines.hxx"
#include "VDiagram.hxx"
#include "VTitle.hxx"
#include "ShapeFactory.hxx"
#include "VAxis.hxx"
#include "VSeriesPlotter.hxx"
#include "CommonConverters.hxx"
#include "macros.hxx"
#include "TitleHelper.hxx"
2003-10-08 16:40:39 +00:00
#include "LegendHelper.hxx"
#include "VLegend.hxx"
#include "PropertyMapper.hxx"
2003-11-08 21:51:06 +00:00
#include "ChartModelHelper.hxx"
2003-10-06 08:58:36 +00:00
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_EXPLICITSUBINCREMENT_HPP_
#include <drafts/com/sun/star/chart2/ExplicitSubIncrement.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_XAXISCONTAINER_HPP_
#include <drafts/com/sun/star/chart2/XAxisContainer.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_XCHARTDOCUMENT_HPP_
#include <drafts/com/sun/star/chart2/XChartDocument.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_XCHARTTYPEGROUP_HPP_
#include <drafts/com/sun/star/chart2/XChartTypeGroup.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_XDATASERIES_HPP_
#include <drafts/com/sun/star/chart2/XDataSeries.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_XDIAGRAM_HPP_
#include <drafts/com/sun/star/chart2/XDiagram.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_XGRIDCONTAINER_HPP_
#include <drafts/com/sun/star/chart2/XGridContainer.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_XSTACKABLESCALEGROUP_HPP_
#include <drafts/com/sun/star/chart2/XStackableScaleGroup.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_CHART2_XTITLED_HPP_
#include <drafts/com/sun/star/chart2/XTitled.hpp>
#endif
2003-12-04 14:58:12 +00:00
#ifndef _DRAFTS_COM_SUN_STAR_LAYOUT_RELATIVEPOSITION_HPP_
#include <drafts/com/sun/star/layout/RelativePosition.hpp>
#endif
2003-12-06 20:57:17 +00:00
#ifndef _DRAFTS_COM_SUN_STAR_LAYOUT_RELATIVESIZE_HPP_
#include <drafts/com/sun/star/layout/RelativeSize.hpp>
#endif
2003-12-04 14:58:12 +00:00
#ifndef _COM_SUN_STAR_DRAWING_LINESTYLE_HPP_
#include <com/sun/star/drawing/LineStyle.hpp>
#endif
2003-10-06 08:58:36 +00:00
//.............................................................................
namespace chart
{
//.............................................................................
using namespace ::com::sun::star;
2003-10-20 08:59:32 +00:00
using namespace ::drafts::com::sun::star;
2003-10-06 08:58:36 +00:00
using namespace ::drafts::com::sun::star::chart2;
ChartView::~ChartView()
{
}
2003-10-06 08:58:36 +00:00
//static
ChartView* ChartView::createView(
const uno::Reference< uno::XComponentContext >& xCC
, const uno::Reference< frame::XModel >& xChartModel
, const uno::Reference<drawing::XDrawPagesSupplier>& xDrawPagesSuplier
, NumberFormatterWrapper* pNumberFormatterWrapper )
{
return new ChartViewImpl(xCC,xChartModel,xDrawPagesSuplier,pNumberFormatterWrapper);
}
ChartViewImpl::ChartViewImpl(
const uno::Reference< uno::XComponentContext >& xCC
, const uno::Reference< frame::XModel >& xChartModel
, const uno::Reference<drawing::XDrawPagesSupplier>& xDrawPagesSuplier
, NumberFormatterWrapper* pNumberFormatterWrapper )
: m_xCC(xCC)
, m_xChartModel(xChartModel)
, m_xShapeFactory(NULL)
, m_xDrawPage(NULL)
, m_xDrawPages(NULL)
2003-10-06 08:58:36 +00:00
, m_pNumberFormatterWrapper( pNumberFormatterWrapper )
{
//get factory from draw model
m_xShapeFactory = uno::Reference<lang::XMultiServiceFactory>( xDrawPagesSuplier, uno::UNO_QUERY );
//create draw page:
m_xDrawPages = xDrawPagesSuplier->getDrawPages ();
m_xDrawPage = m_xDrawPages->insertNewByIndex ( 0 );
2003-10-06 08:58:36 +00:00
}
ChartViewImpl::~ChartViewImpl()
{
m_xDrawPages->remove( m_xDrawPage );
2003-10-06 08:58:36 +00:00
m_xDrawPage = NULL;
}
Matrix4D createTransformationSceneToScreen(
const awt::Point& rPos, const awt::Size& rSize )
{
Matrix4D aM4;
aM4.Scale(double(rSize.Width)/FIXED_SIZE_FOR_3D_CHART_VOLUME
, -double(rSize.Height)/FIXED_SIZE_FOR_3D_CHART_VOLUME, 1.0 );
aM4.Translate(double(rPos.X), double(rPos.Y+rSize.Height-1), 0);
return aM4;
}
uno::Reference< drawing::XShapes > createDiagram(
const uno::Reference< drawing::XShapes>& xPageShapes
, const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
, const awt::Point& rPos, const awt::Size& rSize
, sal_Int32 nDimension
, const uno::Reference< XDiagram > & xDia
)
{
VDiagram aVDiagram(xDia, nDimension);
aVDiagram.init(xPageShapes,xPageShapes,xShapeFactory);
aVDiagram.createShapes(rPos,rSize);
uno::Reference< drawing::XShapes > xTarget = aVDiagram.getCoordinateRegion();
return xTarget;
}
void getCoordinateOrigin( double* fCoordinateOrigin, const uno::Reference< XBoundedCoordinateSystem >& xCoordSys )
{
if(xCoordSys.is())
try
{
uno::Sequence< uno::Any > aCoord( xCoordSys->getOrigin());
if( aCoord.getLength() >= 1 )
aCoord[0]>>=fCoordinateOrigin[0];
if( aCoord.getLength() >= 2 )
aCoord[1]>>=fCoordinateOrigin[1];
if( aCoord.getLength() >= 3 )
aCoord[2]>>=fCoordinateOrigin[2];
}
catch( uno::Exception& ex)
{
2003-10-08 16:40:39 +00:00
ASSERT_EXCEPTION( ex );
2003-10-06 08:58:36 +00:00
}
}
sal_Int32 getDimension( const uno::Reference< XDiagram >& xDiagram )
{
2003-11-08 21:51:06 +00:00
rtl::OUString aChartType;
return ChartModelHelper::getDimensionAndFirstChartType( xDiagram, aChartType );
2003-10-06 08:58:36 +00:00
}
// void getCoordinateSystems( std::vector< VCoordinateSystem >& rVCooSysList, const uno::Reference< XDiagram >& xDiagram )
// {
// uno::Reference< XBoundedCoordinateSystemContainer > xCooSysContainer =
// uno::Reference< XBoundedCoordinateSystemContainer >::query( xDiagram );
// if(xCooSysContainer.is())
// {
// uno::Sequence< uno::Reference< XBoundedCoordinateSystem > > aXCooSysList = xCooSysContainer->getCoordinateSystems();
// for( sal_Int32 nC=0; nC < aXCooSysList.getLength(); nC++)
// {
// VCoordinateSystem aCooSys(aXCooSysList[nC]);
// double fCoordinateOrigin[3] = { 0.0, 0.0, 0.0 };
// getCoordinateOrigin( fCoordinateOrigin, aXCooSysList );
// aCooSys.setOrigin(fCoordinateOrigin);
// rVCooSysList.push_back( aCooSys );
// }
// if(!aXCooSysList.getLength())
// {
// //get coosys from diagram tree
// //...
// }
// }
// }
const VCoordinateSystem* findInCooSysList( const std::vector< VCoordinateSystem >& rVCooSysList
, const uno::Reference< XBoundedCoordinateSystem >& xCooSys )
{
2003-10-08 16:40:39 +00:00
for( size_t nC=0; nC < rVCooSysList.size(); nC++)
2003-10-06 08:58:36 +00:00
{
const VCoordinateSystem& rVCooSys = rVCooSysList[nC];
if(rVCooSys.getModel()==xCooSys)
return &rVCooSys;
}
return NULL;
}
void addCooSysToList( std::vector< VCoordinateSystem >& rVCooSysList
, const uno::Reference< XBoundedCoordinateSystem >& xCooSys
, double fCoordinateOrigin [] )
{
if( !findInCooSysList( rVCooSysList, xCooSys ) )
{
VCoordinateSystem aVCooSys(xCooSys);
aVCooSys.setOrigin(fCoordinateOrigin);
rVCooSysList.push_back( aVCooSys );
}
}
void getAxesAndAddToCooSys( uno::Sequence< uno::Reference< XAxis > >& rAxisList
, const uno::Reference< XDiagram >& xDiagram
, std::vector< VCoordinateSystem >& rVCooSysList )
{
uno::Reference< XAxisContainer > xAxisContainer( xDiagram, uno::UNO_QUERY );
if( xAxisContainer.is())
{
rAxisList = xAxisContainer->getAxes();
for( sal_Int32 nA = 0; nA < rAxisList.getLength(); nA++ )
{
uno::Reference< XAxis > xAxis( rAxisList[nA] );
2003-10-08 16:40:39 +00:00
for( size_t nC=0; nC < rVCooSysList.size(); nC++)
2003-10-06 08:58:36 +00:00
{
if(xAxis->getCoordinateSystem() == rVCooSysList[nC].getModel() )
{
rVCooSysList[nC].addAxis( xAxis );
}
}
}
}
}
void addGridsToCooSys( const uno::Reference< XDiagram >& xDiagram
, std::vector< VCoordinateSystem >& rVCooSysList )
{
uno::Reference< XGridContainer > xGridContainer( xDiagram, uno::UNO_QUERY );
if( xGridContainer.is())
{
uno::Sequence< uno::Reference< XGrid > > aGridList(
xGridContainer->getGrids() );
for( sal_Int32 nA = 0; nA < aGridList.getLength(); nA++ )
{
uno::Reference< XGrid > xGrid( aGridList[nA] );
2003-10-08 16:40:39 +00:00
for( size_t nC=0; nC < rVCooSysList.size(); nC++)
2003-10-06 08:58:36 +00:00
{
if(xGrid->getCoordinateSystem() == rVCooSysList[nC].getModel() )
{
rVCooSysList[nC].addGrid( xGrid );
}
}
}
}
}
2003-11-22 10:53:20 +00:00
void addSeriesToPlotter( const uno::Sequence< uno::Reference< XDataSeriesTreeNode > >& rSeriesList
, VSeriesPlotter* pPlotter
, StackMode eYStackMode )
{
for( sal_Int32 nS = 0; nS < rSeriesList.getLength(); ++nS )
{
uno::Reference< XDataSeries > xDataSeries( rSeriesList[nS], uno::UNO_QUERY );
if(!xDataSeries.is())
continue;
VDataSeries* pTestSeries = new VDataSeries( xDataSeries );
//virtual void addSeries( VDataSeries* pSeries, sal_Int32 xSlot = -1,sal_Int32 ySlot = -1 );
sal_Int32 nXSlot2 = 0;
if(eYStackMode==StackMode_NONE)
nXSlot2=-1;
//@todo
pPlotter->addSeries( pTestSeries, nXSlot2 );
// pPlotter->addSeries( pTestSeries, nXSlot2, nYSlot );
/*
if(nN==nSeriesCount-1)
pPlotter->addSeries( pTestSeries, -1 );
else
pPlotter->addSeries( pTestSeries, 0 );
*/
}
}
2003-10-06 08:58:36 +00:00
void initializeDiagramAndGetCooSys( std::vector< VCoordinateSystem >& rVCooSysList
, const uno::Reference< uno::XComponentContext>& xCC
, const uno::Reference< drawing::XShapes>& xPageShapes
, const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
, NumberFormatterWrapper* pNumberFormatterWrapper
, const awt::Point& rPos, const awt::Size& rSize
2003-12-04 14:58:12 +00:00
, const uno::Reference< frame::XModel >& xChartModel )
2003-10-06 08:58:36 +00:00
{
//------------ get model series from model
2003-12-04 14:58:12 +00:00
uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
2003-10-06 08:58:36 +00:00
if( !xDiagram.is())
return;
sal_Int32 nDimension = getDimension( xDiagram );
//------------ create Diagram shapes
uno::Reference< drawing::XShapes > xTarget = createDiagram( xPageShapes, xShapeFactory, rPos, rSize, nDimension, xDiagram );
//------------ get all coordinatesystems
// getCoordinateSystems( rVCooSysList, xDiagram );
//------------ add series to plotter and thus prepare him for providing minimum and maximum values
uno::Reference< XDataSeriesTreeParent > xTree = xDiagram->getTree();
uno::Sequence< uno::Reference< XDataSeriesTreeNode > > aChartTypes( xTree->getChildren() );
for( sal_Int32 i = 0; i < aChartTypes.getLength(); ++i )
{
//iterate through different charttypes:
uno::Reference< XChartTypeGroup > xChartTypeGroup( aChartTypes[i], uno::UNO_QUERY );
DBG_ASSERT(xChartTypeGroup.is(),"First node at the diagram tree needs to be a ChartTypeGroup");
if( !xChartTypeGroup.is() )
continue;
::std::auto_ptr< VSeriesPlotter > apPlotter( VSeriesPlotter::createSeriesPlotter( xChartTypeGroup->getChartType() ) );
2003-10-06 08:58:36 +00:00
//------------ add series to plotter and thus prepare him for providing minimum and maximum values
sal_Int32 nXSlot = -1;
sal_Int32 nYSlot = -1;
uno::Sequence< uno::Reference< XDataSeriesTreeNode > > aXSlots( xChartTypeGroup->getChildren() );
for( sal_Int32 nX = 0; nX < aXSlots.getLength(); ++nX )
{
2003-11-22 10:53:20 +00:00
uno::Reference< XDataSeriesTreeParent > xXSlot( aXSlots[nX], uno::UNO_QUERY );
2003-10-06 08:58:36 +00:00
DBG_ASSERT( xXSlot.is(), "a node for the first dimension of a chart tree should always be a parent" );
if(!xXSlot.is())
2003-11-08 21:51:06 +00:00
continue;
2003-11-22 10:53:20 +00:00
uno::Reference< XStackableScaleGroup > xStackGroup( xXSlot, uno::UNO_QUERY );
if( xStackGroup.is() && xStackGroup->getStackMode()==StackMode_STACKED)
2003-10-06 08:58:36 +00:00
nXSlot++;
2003-11-22 10:53:20 +00:00
uno::Sequence< uno::Reference< XDataSeriesTreeNode > > aYSlots( xXSlot->getChildren() );
2003-10-06 08:58:36 +00:00
for( sal_Int32 nY = 0; nY < aYSlots.getLength(); ++nY )
{
2003-11-22 10:53:20 +00:00
uno::Reference< XDataSeriesTreeParent > xYSlot( aYSlots[nY], uno::UNO_QUERY );
2003-10-06 08:58:36 +00:00
DBG_ASSERT( xYSlot.is(), "a node for the second dimension of a chart tree should always be a parent" );
if(!xYSlot.is())
2003-11-08 21:51:06 +00:00
continue;
2003-10-08 16:40:39 +00:00
xStackGroup.set( uno::Reference< XStackableScaleGroup >::query( xYSlot ));
2003-10-06 08:58:36 +00:00
StackMode aYStackMode = StackMode_NONE;
if(xStackGroup.is())
aYStackMode = xStackGroup->getStackMode();
if(aYStackMode==StackMode_STACKED)
nYSlot++;
2003-11-22 10:53:20 +00:00
if( 2 == nDimension )
{
uno::Reference< XScaleGroup > xScaleGroup( xYSlot, uno::UNO_QUERY );
{
double fCoordinateOrigin[3] = { 0.0, 0.0, 0.0 };
getCoordinateOrigin( fCoordinateOrigin, xScaleGroup->getCoordinateSystem() );
addCooSysToList(rVCooSysList,xScaleGroup->getCoordinateSystem(),fCoordinateOrigin);
}
addSeriesToPlotter( xYSlot->getChildren(), apPlotter.get(), aYStackMode );
}
else
2003-10-06 08:58:36 +00:00
{
2003-11-22 10:53:20 +00:00
uno::Sequence< uno::Reference< XDataSeriesTreeNode > > aZSlots( xYSlot->getChildren() );
for( sal_Int32 nZ = 0; nZ < aZSlots.getLength(); ++nZ )
{
2003-11-26 13:52:41 +00:00
uno::Reference< XScaleGroup > xScaleGroup( aZSlots[nZ], uno::UNO_QUERY );
if(xScaleGroup.is())
2003-11-22 10:53:20 +00:00
{
double fCoordinateOrigin[3] = { 0.0, 0.0, 0.0 };
getCoordinateOrigin( fCoordinateOrigin, xScaleGroup->getCoordinateSystem() );
addCooSysToList(rVCooSysList,xScaleGroup->getCoordinateSystem(),fCoordinateOrigin);
}
2003-11-26 13:52:41 +00:00
uno::Reference< XDataSeriesTreeParent > xZSlot( aZSlots[nZ], uno::UNO_QUERY );
DBG_ASSERT( xZSlot.is(), "a node for the third dimension of a 3 dimensional chart tree should always be a parent" );
if(!xZSlot.is())
continue;
2003-11-22 10:53:20 +00:00
addSeriesToPlotter( xZSlot->getChildren(), apPlotter.get(), aYStackMode );
}
2003-10-06 08:58:36 +00:00
}
}
}
//------------ get all axes from model and add to VCoordinateSystems
uno::Sequence< uno::Reference< XAxis > > aAxisList;
getAxesAndAddToCooSys( aAxisList, xDiagram, rVCooSysList );
addGridsToCooSys( xDiagram, rVCooSysList );
//------------ iterate through all coordinate systems
2003-10-08 16:40:39 +00:00
for( size_t nC=0; nC < rVCooSysList.size(); nC++)
2003-10-06 08:58:36 +00:00
{
//------------ create explicit scales and increments
VCoordinateSystem& rVCooSys = rVCooSysList[nC];
rVCooSys.doAutoScale( apPlotter.get() );
const uno::Sequence< ExplicitScaleData >& rExplicitScales = rVCooSys.getExplicitScales();
const uno::Sequence< ExplicitIncrementData >& rExplicitIncrements = rVCooSys.getExplicitIncrements();
double fCoordinateOrigin[3] = { 0.0, 0.0, 0.0 };
for( sal_Int32 nDim = 0; nDim < 3; nDim++ )
fCoordinateOrigin[nDim] = rVCooSys.getOriginByDimension( nDim );
Matrix4D aM4_SceneToScreen( createTransformationSceneToScreen(rPos,rSize) );
drawing::HomogenMatrix aHM_SceneToScreen( Matrix4DToHomogenMatrix(aM4_SceneToScreen) );
//------------ create axes --- @todo do auto layout / fontscaling
for( nDim = 0; nDim < 3; nDim++ )
{
uno::Reference< XAxis > xAxis = rVCooSys.getAxisByDimension(nDim);
if(xAxis.is()
&&2==nDimension) //@todo remove this restriction if 3D axes are available
{
AxisProperties aAxisProperties;
aAxisProperties.m_xAxisModel = xAxis;
aAxisProperties.m_pfExrtaLinePositionAtOtherAxis =
new double(nDim==1?fCoordinateOrigin[0]:fCoordinateOrigin[1]);
aAxisProperties.m_bTESTTEST_HorizontalAdjustmentIsLeft = sal_False;
2003-11-19 15:40:47 +00:00
aAxisProperties.m_aReferenceSize = rSize;
2003-10-06 08:58:36 +00:00
//-------------------
VAxis aAxis(aAxisProperties,pNumberFormatterWrapper);
aAxis.setMeterData( rExplicitScales[nDim], rExplicitIncrements[nDim] );
aAxis.init(xTarget,xPageShapes,xShapeFactory);
if(2==nDimension)
aAxis.setTransformationSceneToScreen( aHM_SceneToScreen );
aAxis.setScales( rExplicitScales );
aAxis.createShapes();
}
}
//------------ create grids
rVCooSys.createGridShapes( xShapeFactory, xTarget, aHM_SceneToScreen );
//------------ set scale to plotter
apPlotter->init(xTarget,xPageShapes,xShapeFactory);
if(2==nDimension)
apPlotter->setTransformationSceneToScreen( aHM_SceneToScreen );
apPlotter->setScales( rExplicitScales );
apPlotter->createShapes();
}
}
}
//-------------------------------------------------------------
//-------------------------------------------------------------
//-------------------------------------------------------------
void ChartViewImpl::getExplicitValuesForMeter(
uno::Reference< XMeter > xMeter
, ExplicitScaleData& rExplicitScale
, ExplicitIncrementData& rExplicitIncrement
, double& rfExplicitOrigin )
{
if(!xMeter.is())
return;
uno::Reference< XBoundedCoordinateSystem > xCooSys = xMeter->getCoordinateSystem();
const VCoordinateSystem* pVCooSys = findInCooSysList(m_aVCooSysList,xCooSys);
if(!pVCooSys)
return;
const uno::Sequence< ExplicitScaleData >& rScales =pVCooSys->getExplicitScales();
const uno::Sequence< ExplicitIncrementData >& rIncrements =pVCooSys->getExplicitIncrements();
sal_Int32 nDim = xMeter->getRepresentedDimension();
if(nDim<=rScales.getLength())
rExplicitScale=rScales[nDim];
if(nDim<=rIncrements.getLength())
rExplicitIncrement=rIncrements[nDim];
rfExplicitOrigin = pVCooSys->getOriginByDimension( nDim );
}
2003-12-12 19:15:30 +00:00
double lcl_getPageLayoutDistancePercentage()
{
return 0.02;
}
2003-10-08 16:40:39 +00:00
bool getPosAndSizeForDiagram(
awt::Point& rOutPos, awt::Size& rOutSize
2003-12-04 14:58:12 +00:00
, const awt::Rectangle& rSpaceLeft
, const awt::Size & rPageSize
, const uno::Reference< XDiagram > & xDiagram )
2003-10-06 08:58:36 +00:00
{
//@todo: we need a size dependent on the axis labels
2003-12-12 19:15:30 +00:00
awt::Rectangle aRemainingSpace(rSpaceLeft);
{
sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage());
sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage());
aRemainingSpace.X+=nXDistance;
aRemainingSpace.Width-=2*nXDistance;
aRemainingSpace.Y+=nYDistance;
aRemainingSpace.Height-=2*nYDistance;
}
if(aRemainingSpace.Width <= 0 || aRemainingSpace.Height <= 0 )
2003-10-06 08:58:36 +00:00
return false;
2003-12-12 19:15:30 +00:00
//long nHeight = aRemainingSpace.Height * 5 / 6;
2003-10-14 13:45:06 +00:00
// (1 - 5/6) / 2 = 1/12
2003-12-12 19:15:30 +00:00
//long nOffsetY = aRemainingSpace.Y + aRemainingSpace.Height / 12;
long nHeight = aRemainingSpace.Height * 11 / 12;
long nOffsetY = aRemainingSpace.Y;
2003-10-06 08:58:36 +00:00
2003-12-12 19:15:30 +00:00
long nWidth = aRemainingSpace.Width * 5 / 6;
2003-10-14 13:45:06 +00:00
// (1 - 5/6) / 2 = 1/12
2003-12-12 19:15:30 +00:00
long nOffsetX = aRemainingSpace.X + aRemainingSpace.Width / 12;
2003-10-06 08:58:36 +00:00
if( nHeight <= 0 || nWidth <= 0 )
return false;
2003-12-06 20:57:17 +00:00
uno::Reference< beans::XPropertySet > xProp(xDiagram, uno::UNO_QUERY);
2003-12-04 14:58:12 +00:00
//size:
2003-12-06 20:57:17 +00:00
::drafts::com::sun::star::layout::RelativeSize aRelativeSize;
if( xProp.is() && (xProp->getPropertyValue( C2U( "RelativeSize" ) )>>=aRelativeSize) )
{
2003-12-12 19:15:30 +00:00
rOutSize.Height = static_cast<sal_Int32>(aRelativeSize.Secondary*rPageSize.Height);
rOutSize.Width = static_cast<sal_Int32>(aRelativeSize.Primary*rPageSize.Width);
2003-12-06 20:57:17 +00:00
}
else
rOutSize = awt::Size(nWidth,nHeight);
2003-12-04 14:58:12 +00:00
//position:
::drafts::com::sun::star::layout::RelativePosition aRelativePosition;
if( xProp.is() && (xProp->getPropertyValue( C2U( "RelativePosition" ) )>>=aRelativePosition) )
{
//@todo decide wether x is primary or secondary
//the anchor point at the page is in the middle of the page
double fX = rPageSize.Width/2.0+aRelativePosition.Primary*rPageSize.Width;
double fY = rPageSize.Height/2.0+aRelativePosition.Secondary*rPageSize.Height;
//the anchor point at the diagram object is in the middle
fY -= rOutSize.Height/2;
fX -= rOutSize.Width/2;
rOutPos.X = static_cast<sal_Int32>(fX);
rOutPos.Y = static_cast<sal_Int32>(fY);
}
else
rOutPos = awt::Point(nOffsetX,nOffsetY);
2003-10-06 08:58:36 +00:00
return true;
}
2003-12-12 19:15:30 +00:00
enum TitleAlignment { ALIGN_LEFT, ALIGN_TOP, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_Z };
void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment
, awt::Rectangle& rDiagramPlusAxesRect, const awt::Size & rPageSize )
{
if(!pVTitle)
return;
awt::Point aNewPosition(0,0);
awt::Size aTitleSize = pVTitle->getFinalSize();
sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage());
sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage());
switch( eAlignment )
{
case ALIGN_BOTTOM:
aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2
, rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height + aTitleSize.Height/2 + nYDistance );
break;
case ALIGN_LEFT:
aNewPosition = awt::Point( rDiagramPlusAxesRect.X - aTitleSize.Width/2 - nXDistance
, rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 );
break;
case ALIGN_Z:
aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance
, rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height - aTitleSize.Height/2 );
break;
default:
break;
}
pVTitle->changePosition( aNewPosition );
}
std::auto_ptr<VTitle> createTitle( const uno::Reference< XTitle >& xTitle
2003-10-06 08:58:36 +00:00
, const uno::Reference< drawing::XShapes>& xPageShapes
, const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
2003-12-12 19:15:30 +00:00
, awt::Rectangle& rRemainingSpace
2003-11-14 14:25:55 +00:00
, const awt::Size & rPageSize
2003-12-12 19:15:30 +00:00
, TitleAlignment eAlignment
, bool& rbAutoPosition )
2003-10-06 08:58:36 +00:00
{
2003-12-12 19:15:30 +00:00
std::auto_ptr<VTitle> apVTitle;
2003-10-06 08:58:36 +00:00
if(xTitle.is())
{
2003-12-12 19:15:30 +00:00
//create title
double fAdditionalRotationAngleDegree = 0.0;
if( ALIGN_LEFT==eAlignment)
fAdditionalRotationAngleDegree = 90.0;
apVTitle = std::auto_ptr<VTitle>(new VTitle(xTitle,fAdditionalRotationAngleDegree));
apVTitle->init(xPageShapes,xShapeFactory);
apVTitle->createShapes( awt::Point(0,0), rPageSize );
awt::Size aTitleSize = apVTitle->getFinalSize();
//position
rbAutoPosition=true;
awt::Point aNewPosition(0,0);
sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage());
sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage());
2003-12-04 14:58:12 +00:00
::drafts::com::sun::star::layout::RelativePosition aRelativePosition;
uno::Reference< beans::XPropertySet > xProp(xTitle, uno::UNO_QUERY);
if( xProp.is() && (xProp->getPropertyValue( C2U( "RelativePosition" ) )>>=aRelativePosition) )
{
2003-12-12 19:15:30 +00:00
rbAutoPosition = false;
2003-12-04 14:58:12 +00:00
//@todo decide wether x is primary or secondary
aNewPosition.X = static_cast<sal_Int32>(aRelativePosition.Primary*rPageSize.Width);
aNewPosition.Y = static_cast<sal_Int32>(aRelativePosition.Secondary*rPageSize.Height);
//the anchor point at the title object is top/middle
aNewPosition.Y += aTitleSize.Height/2;
}
2003-12-12 19:15:30 +00:00
else //auto position
2003-12-04 14:58:12 +00:00
{
2003-12-12 19:15:30 +00:00
switch( eAlignment )
{
case ALIGN_TOP:
aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2
, rRemainingSpace.Y + aTitleSize.Height/2 + nYDistance );
break;
case ALIGN_BOTTOM:
aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2
, rRemainingSpace.Y + rRemainingSpace.Height - aTitleSize.Height/2 - nYDistance );
break;
case ALIGN_LEFT:
aNewPosition = awt::Point( rRemainingSpace.X + aTitleSize.Width/2 + nXDistance
, rRemainingSpace.Y + rRemainingSpace.Height/2 );
break;
case ALIGN_RIGHT:
aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width - aTitleSize.Width/2 - nXDistance
, rRemainingSpace.Y + rRemainingSpace.Height/2 );
break;
default:
break;
}
2003-12-04 14:58:12 +00:00
}
2003-12-12 19:15:30 +00:00
apVTitle->changePosition( aNewPosition );
2003-12-04 14:58:12 +00:00
2003-12-12 19:15:30 +00:00
//remaining space
switch( eAlignment )
{
case ALIGN_TOP:
rRemainingSpace.Y += ( aTitleSize.Height + nYDistance );
rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance );
break;
case ALIGN_BOTTOM:
rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance );
break;
case ALIGN_LEFT:
rRemainingSpace.X += ( aTitleSize.Width + nXDistance );
rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance );
break;
case ALIGN_RIGHT:
rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance );
break;
default:
break;
}
2003-10-06 08:58:36 +00:00
}
2003-12-12 19:15:30 +00:00
return apVTitle;
2003-10-06 08:58:36 +00:00
}
2003-12-12 19:15:30 +00:00
bool createLegend( const uno::Reference< XLegend > & xLegend
2003-10-08 16:40:39 +00:00
, const uno::Reference< drawing::XShapes>& xPageShapes
, const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
2003-12-12 19:15:30 +00:00
, awt::Rectangle & rOutSpaceLeft
, const awt::Size & rPageSize
2003-12-17 15:43:22 +00:00
, const uno::Reference< frame::XModel > & xModel )
2003-10-08 16:40:39 +00:00
{
2003-10-20 08:59:32 +00:00
if( VLegend::isVisible( xLegend ))
2003-10-08 16:40:39 +00:00
{
VLegend aVLegend( xLegend );
2003-12-17 15:43:22 +00:00
aVLegend.init( xPageShapes, xShapeFactory, xModel );
aVLegend.createShapes( awt::Size( rOutSpaceLeft.Width, rOutSpaceLeft.Height ),
rPageSize );
aVLegend.changePosition( rOutSpaceLeft, rPageSize );
2003-12-12 19:15:30 +00:00
return true;
2003-10-08 16:40:39 +00:00
}
2003-12-12 19:15:30 +00:00
return false;
2003-10-08 16:40:39 +00:00
}
void formatPage(
const uno::Reference< frame::XModel > & xModel
, const awt::Size rPageSize
, const uno::Reference< drawing::XShapes >& xTarget
, const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
)
{
try
{
uno::Reference< XChartDocument > xChartDoc( xModel, uno::UNO_QUERY );
OSL_ASSERT( xChartDoc.is());
if( ! xChartDoc.is())
return;
uno::Reference< beans::XPropertySet > xModelPage( xChartDoc->getPageBackground());
if( ! xModelPage.is())
return;
uno::Reference< beans::XPropertySet > xPageProp( xTarget, uno::UNO_QUERY );
// the following is just a workaround as the draw page is no XPropertySet
// ------------ workaround
if( ! xPageProp.is() )
{
// if we get here, we need a shape to place on the page
if( xShapeFactory.is())
{
uno::Reference< drawing::XShape > xShape(
xShapeFactory->createInstance(
C2U( "com.sun.star.drawing.RectangleShape" )), uno::UNO_QUERY );
if( xTarget.is() &&
xShape.is())
{
xTarget->add( xShape );
xShape->setSize( rPageSize );
xPageProp.set( xShape, uno::UNO_QUERY );
if( xPageProp.is())
xPageProp->setPropertyValue( C2U("LineStyle"), uno::makeAny( drawing::LineStyle_NONE ));
}
}
}
// ------------ workaround
if( xPageProp.is())
{
tPropertyNameValueMap aFillValueMap;
tMakePropertyNameMap aCharNameMap = PropertyMapper::getPropertyNameMapForFillProperties();
PropertyMapper::getValueMap( aFillValueMap, aCharNameMap, xModelPage );
tNameSequence aNames;
tAnySequence aValues;
PropertyMapper::getMultiPropertyListsFromValueMap( aNames, aValues, aFillValueMap );
PropertyMapper::setMultiProperties( aNames, aValues, xPageProp );
}
}
catch( uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
}
}
2003-10-06 08:58:36 +00:00
bool ChartViewImpl::create( const awt::Size& rPageSize )
{
uno::Reference<drawing::XShapes> xPageShapes =
uno::Reference<drawing::XShapes>( m_xDrawPage, uno::UNO_QUERY );
//------------ apply fill properties to page
// todo: it would be nicer to just pass the page m_xDrawPage and format it,
// but the page we have here does not support XPropertySet
formatPage( m_xChartModel, rPageSize, xPageShapes, m_xShapeFactory );
2003-10-06 08:58:36 +00:00
2003-12-12 19:15:30 +00:00
//sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage());
awt::Rectangle aRemainingSpace( 0, 0, rPageSize.Width, rPageSize.Height );
//create the group shape for diagram and axes first to have title and legends on top of it
uno::Reference< drawing::XShapes > xDiagramPlusAxesGroup_Shapes = ShapeFactory(m_xShapeFactory).createGroup2D(xPageShapes,C2U("CID/Diagram=XXX_CID"));//@todo read CID from model
2003-12-12 19:15:30 +00:00
//------------ create some titles
std::auto_ptr<VTitle> apVTitle(0);
bool bAutoPositionDummy;
2003-10-06 08:58:36 +00:00
//------------ create main title shape
2003-12-12 19:15:30 +00:00
createTitle( TitleHelper::getTitle( TitleHelper::MAIN_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory
, aRemainingSpace, rPageSize, ALIGN_TOP, bAutoPositionDummy );
if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2003-10-06 08:58:36 +00:00
return true;
//------------ create sub title shape
2003-12-12 19:15:30 +00:00
createTitle( TitleHelper::getTitle( TitleHelper::SUB_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory
, aRemainingSpace, rPageSize, ALIGN_TOP, bAutoPositionDummy );
if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
2003-10-06 08:58:36 +00:00
return true;
2003-10-08 16:40:39 +00:00
//------------ create legend
2003-12-12 19:15:30 +00:00
createLegend( LegendHelper::getLegend( m_xChartModel ), xPageShapes, m_xShapeFactory
2003-12-17 15:43:22 +00:00
, aRemainingSpace, rPageSize, m_xChartModel );
2003-12-12 19:15:30 +00:00
if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
return true;
//------------ create x axis title
bool bAutoPosition_XTitle;
std::auto_ptr<VTitle> apVTitle_X( createTitle( TitleHelper::getTitle( TitleHelper::X_AXIS_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory
, aRemainingSpace, rPageSize, ALIGN_BOTTOM, bAutoPosition_XTitle) );
if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
return true;
//------------ create y axis title
bool bAutoPosition_YTitle;
std::auto_ptr<VTitle> apVTitle_Y( createTitle( TitleHelper::getTitle( TitleHelper::Y_AXIS_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory
, aRemainingSpace, rPageSize, ALIGN_LEFT, bAutoPosition_YTitle) );
if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
return true;
//------------ create z axis title
bool bAutoPosition_ZTitle;
std::auto_ptr<VTitle> apVTitle_Z( createTitle( TitleHelper::getTitle( TitleHelper::Z_AXIS_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory
, aRemainingSpace, rPageSize, ALIGN_RIGHT, bAutoPosition_ZTitle) );
if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0)
return true;
2003-10-08 16:40:39 +00:00
2003-10-06 08:58:36 +00:00
//------------ create complete diagram shape (inclusive axis and series)
awt::Point aPosDia;
awt::Size aSizeDia;
2003-12-12 19:15:30 +00:00
if( getPosAndSizeForDiagram( aPosDia, aSizeDia, aRemainingSpace, rPageSize, ChartModelHelper::findDiagram( m_xChartModel ) ) )
{
//create diagram and all its content
2003-10-06 08:58:36 +00:00
initializeDiagramAndGetCooSys( m_aVCooSysList
2003-12-12 19:15:30 +00:00
, m_xCC, xDiagramPlusAxesGroup_Shapes, m_xShapeFactory, m_pNumberFormatterWrapper
, aPosDia ,aSizeDia, m_xChartModel );
//correct axis title position
uno::Reference< drawing::XShape > xDiagramPlusAxesGroup_Shape( xDiagramPlusAxesGroup_Shapes, uno::UNO_QUERY );
awt::Point aPos = xDiagramPlusAxesGroup_Shape->getPosition();
awt::Size aSize = xDiagramPlusAxesGroup_Shape->getSize();
awt::Rectangle aRect(aPos.X,aPos.Y,aSize.Width,aSize.Height);
awt::Rectangle aDiagramPlusAxesRect(aPos.X,aPos.Y,aSize.Width,aSize.Height);
if(bAutoPosition_XTitle)
changePositionOfAxisTitle( apVTitle_X.get(), ALIGN_BOTTOM, aDiagramPlusAxesRect, rPageSize );
if(bAutoPosition_YTitle)
changePositionOfAxisTitle( apVTitle_Y.get(), ALIGN_LEFT, aDiagramPlusAxesRect, rPageSize );
if(bAutoPosition_ZTitle)
changePositionOfAxisTitle( apVTitle_Z.get(), ALIGN_Z, aDiagramPlusAxesRect, rPageSize );
}
2003-10-06 08:58:36 +00:00
return true;
}
//.............................................................................
} //namespace chart
//.............................................................................