1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include "ChartView.hxx"
23 #include "chartview/DrawModelWrapper.hxx"
24 #include "NumberFormatterWrapper.hxx"
25 #include "ViewDefines.hxx"
26 #include "VDiagram.hxx"
28 #include "AbstractShapeFactory.hxx"
29 #include "VCoordinateSystem.hxx"
30 #include "VSeriesPlotter.hxx"
31 #include "CommonConverters.hxx"
33 #include "TitleHelper.hxx"
34 #include "LegendHelper.hxx"
35 #include "VLegend.hxx"
36 #include "PropertyMapper.hxx"
37 #include "ChartModelHelper.hxx"
38 #include "ChartTypeHelper.hxx"
39 #include "ScaleAutomatism.hxx"
40 #include "MinimumAndMaximumSupplier.hxx"
41 #include "ObjectIdentifier.hxx"
42 #include "DiagramHelper.hxx"
43 #include "RelativePositionHelper.hxx"
44 #include "servicenames.hxx"
45 #include "AxisHelper.hxx"
46 #include "AxisIndexDefines.hxx"
47 #include "ControllerLockGuard.hxx"
48 #include "BaseGFXHelper.hxx"
49 #include "DataSeriesHelper.hxx"
50 #include "DateHelper.hxx"
51 #include "defines.hxx"
52 #include <unonames.hxx>
53 #include <GL3DBarChart.hxx>
55 #include <editeng/frmdiritem.hxx>
57 #include <tools/globname.hxx>
58 #include <comphelper/scopeguard.hxx>
59 #include <comphelper/servicehelper.hxx>
60 #include <cppuhelper/supportsservice.hxx>
61 #include <boost/bind.hpp>
62 #include <unotools/streamwrap.hxx>
63 #include <unotools/localedatawrapper.hxx>
64 #include <svx/charthelper.hxx>
65 #include <svx/svdpage.hxx>
66 #include <svx/unopage.hxx>
67 #include <svx/unoshape.hxx>
68 #include <vcl/svapp.hxx>
69 #include <osl/mutex.hxx>
70 #include <svx/unofill.hxx>
71 #include <vcl/openglwin.hxx>
72 #include <vcl/opengl/OpenGLContext.hxx>
74 #include <drawinglayer/XShapeDumper.hxx>
78 #include <com/sun/star/awt/Size.hpp>
79 #include <com/sun/star/awt/Point.hpp>
80 #include <com/sun/star/chart/ChartAxisPosition.hpp>
81 #include <com/sun/star/chart/DataLabelPlacement.hpp>
82 #include <com/sun/star/chart/MissingValueTreatment.hpp>
83 #include <com/sun/star/chart2/StackingDirection.hpp>
84 #include <com/sun/star/chart2/XChartDocument.hpp>
85 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
86 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
87 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
88 #include <com/sun/star/chart2/XTitled.hpp>
89 #include <com/sun/star/chart2/RelativePosition.hpp>
90 #include <com/sun/star/chart2/RelativeSize.hpp>
91 #include <com/sun/star/drawing/FillStyle.hpp>
92 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
93 #include <com/sun/star/drawing/LineStyle.hpp>
94 #include <com/sun/star/drawing/XShapeGroup.hpp>
95 #include <com/sun/star/drawing/XShapeDescriptor.hpp>
96 #include <com/sun/star/document/XExporter.hpp>
97 #include <com/sun/star/document/XFilter.hpp>
98 #include <com/sun/star/embed/Aspects.hpp>
99 #include <com/sun/star/io/XSeekable.hpp>
100 #include <com/sun/star/util/XModifiable.hpp>
101 #include <com/sun/star/util/XRefreshable.hpp>
102 #include <com/sun/star/util/NumberFormat.hpp>
103 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
104 #include <com/sun/star/text/XText.hpp>
105 #include <com/sun/star/text/XTextDocument.hpp>
106 #include <com/sun/star/text/WritingMode2.hpp>
107 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
108 #include <com/sun/star/view/XSelectionSupplier.hpp>
109 #include <svl/languageoptions.hxx>
110 #include <comphelper/classids.hxx>
111 #include "servicenames_charttypes.hxx"
113 #include <rtl/strbuf.hxx>
114 #include <rtl/ustring.hxx>
116 #include <osl/conditn.hxx>
117 #include <osl/time.h>
119 #include <boost/shared_ptr.hpp>
120 #include <boost/ptr_container/ptr_vector.hpp>
124 using namespace ::com::sun::star
;
125 using namespace ::com::sun::star::chart2
;
126 using ::com::sun::star::uno::Reference
;
127 using ::com::sun::star::uno::Sequence
;
128 using ::com::sun::star::uno::Any
;
132 class theExplicitValueProviderUnoTunnelId
: public rtl::Static
<UnoTunnelIdInit
, theExplicitValueProviderUnoTunnelId
> {};
134 typedef std::pair
< sal_Int32
, sal_Int32
> tFullAxisIndex
; //first index is the dimension, second index is the axis index that indicates whether this is a main or secondary axis
135 typedef std::map
< VCoordinateSystem
*, tFullAxisIndex
> tCoordinateSystemMap
;
137 /** This class handles a collection of coordinate systems and is used for
138 * executing some action on all coordinate systems such as
139 * `prepareAutomaticAxisScaling` and `setExplicitScaleAndIncrement`.
140 * Moreover it contains the `aAutoScaling` object that is an instance of
141 * the `ScaleAutomatism` class. The initialization of `aAutoScaling` is
142 * performed in the `SeriesPlotterContainer::initAxisUsageList` method and is
143 * used in the `SeriesPlotterContainer::doAutoScaling` for calculating explicit
144 * scale and increment objects (see `SeriesPlotterContainer::doAutoScaling`).
151 void addCoordinateSystem( VCoordinateSystem
* pCooSys
, sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
);
152 ::std::vector
< VCoordinateSystem
* > getCoordinateSystems( sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
);
153 sal_Int32
getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex
);
155 void prepareAutomaticAxisScaling( ScaleAutomatism
& rScaleAutomatism
, sal_Int32 nDimIndex
, sal_Int32 nAxisIndex
);
156 void setExplicitScaleAndIncrement( sal_Int32 nDimIndex
, sal_Int32 nAxisIndex
, const ExplicitScaleData
& rScale
, const ExplicitIncrementData
& rInc
);
158 ScaleAutomatism aAutoScaling
;
161 tCoordinateSystemMap aCoordinateSystems
;
162 std::map
< sal_Int32
, sal_Int32
> aMaxIndexPerDimension
;
165 AxisUsage::AxisUsage()
166 : aAutoScaling(AxisHelper::createDefaultScale(), Date(Date::SYSTEM
))
170 AxisUsage::~AxisUsage()
172 aCoordinateSystems
.clear();
175 void AxisUsage::addCoordinateSystem( VCoordinateSystem
* pCooSys
, sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
)
180 tFullAxisIndex
aFullAxisIndex( nDimensionIndex
, nAxisIndex
);
181 tCoordinateSystemMap::const_iterator
aFound( aCoordinateSystems
.find(pCooSys
) );
183 //use one scale only once for each coordinate system
184 //main axis are preferred over secondary axis
185 //value scales are preferred
186 if(aFound
!=aCoordinateSystems
.end())
188 sal_Int32 nFoundAxisIndex
= aFound
->second
.second
;
189 if( nFoundAxisIndex
< nAxisIndex
)
191 sal_Int32 nFoundDimension
= aFound
->second
.first
;
192 if( nFoundDimension
==1 )
194 if( nFoundDimension
< nDimensionIndex
)
197 aCoordinateSystems
[pCooSys
] = aFullAxisIndex
;
199 //set maximum scale index
200 std::map
< sal_Int32
, sal_Int32
>::const_iterator aIter
= aMaxIndexPerDimension
.find(nDimensionIndex
);
201 if( aIter
!= aMaxIndexPerDimension
.end() )
203 sal_Int32 nCurrentMaxIndex
= aIter
->second
;
204 if( nCurrentMaxIndex
< nAxisIndex
)
205 aMaxIndexPerDimension
[nDimensionIndex
]=nAxisIndex
;
208 aMaxIndexPerDimension
[nDimensionIndex
]=nAxisIndex
;
211 ::std::vector
< VCoordinateSystem
* > AxisUsage::getCoordinateSystems( sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
)
213 ::std::vector
< VCoordinateSystem
* > aRet
;
215 tCoordinateSystemMap::const_iterator aIter
;
216 for( aIter
= aCoordinateSystems
.begin(); aIter
!=aCoordinateSystems
.end();++aIter
)
218 if( aIter
->second
.first
!= nDimensionIndex
)
220 if( aIter
->second
.second
!= nAxisIndex
)
222 aRet
.push_back( aIter
->first
);
228 sal_Int32
AxisUsage::getMaxAxisIndexForDimension( sal_Int32 nDimensionIndex
)
231 std::map
< sal_Int32
, sal_Int32
>::const_iterator aIter
= aMaxIndexPerDimension
.find(nDimensionIndex
);
232 if( aIter
!= aMaxIndexPerDimension
.end() )
233 nRet
= aIter
->second
;
237 void AxisUsage::prepareAutomaticAxisScaling( ScaleAutomatism
& rScaleAutomatism
, sal_Int32 nDimIndex
, sal_Int32 nAxisIndex
)
239 std::vector
<VCoordinateSystem
*> aVCooSysList
= getCoordinateSystems(nDimIndex
, nAxisIndex
);
240 for (size_t i
= 0, n
= aVCooSysList
.size(); i
< n
; ++i
)
241 aVCooSysList
[i
]->prepareAutomaticAxisScaling(rScaleAutomatism
, nDimIndex
, nAxisIndex
);
244 void AxisUsage::setExplicitScaleAndIncrement(
245 sal_Int32 nDimIndex
, sal_Int32 nAxisIndex
, const ExplicitScaleData
& rScale
, const ExplicitIncrementData
& rInc
)
247 std::vector
<VCoordinateSystem
*> aVCooSysList
= getCoordinateSystems(nDimIndex
, nAxisIndex
);
248 for (size_t i
= 0, n
= aVCooSysList
.size(); i
< n
; ++i
)
249 aVCooSysList
[i
]->setExplicitScaleAndIncrement(nDimIndex
, nAxisIndex
, rScale
, rInc
);
252 typedef boost::ptr_vector
<VSeriesPlotter
> SeriesPlottersType
;
254 /** This class is a container of `SeriesPlotter` objects (such as `PieChart`
255 * instances). It is used for initializing coordinate systems, axes and scales
256 * of all series plotters which belongs to the container.
258 class SeriesPlotterContainer
261 SeriesPlotterContainer( std::vector
< VCoordinateSystem
* >& rVCooSysList
);
262 ~SeriesPlotterContainer();
264 /** It is used to set coordinate systems (`m_rVCooSysList`), this method
265 * is invoked by `ChartView::createShapes2D` before of
266 * `ChartView::impl_createDiagramAndContent`.
267 * Coordinate systems are retrieved through the `XCoordinateSystemContainer`
268 * interface implemented by a diagram object which is provided by the
269 * `ChartModel` object passed to the method (`rChartModel.getFirstDiagram()`).
271 * It is used for creating series plotters and appending them
272 * to `m_aSeriesPlotterList`. The created series plotters are initialized
273 * through data (number formats supplier, color scheme, data series),
274 * extracted from the chart model or the diagram objects. An exception is
275 * the explicit category provider that is retrieved through the
276 * `VCoordinateSystem` object used by the series plotter.
278 * It sets the minimum-maximum supplier for a coordinate system:
279 * this supplier is the series plotter itself which utilizes the given
280 * coordinate system. In fact `VSeriesPlotter` has `MinimumMaximumSupplier`
281 * as one of its base classes.
282 * Hence, for instance, a `PieChart`, which is a series plotter, is
283 * a `MinimumMaximumSupplier`, too.
285 void initializeCooSysAndSeriesPlotter( ChartModel
& rModel
);
287 /** This method is invoked by `ChartView::impl_createDiagramAndContent`.
288 * It iterates on every axis of every coordinate systems, and if the axis
289 * is not yet present in `m_aAxisUsageList` it creates a new `AxisUsage`
290 * object and initialize its `aAutoScaling` member to the `ScaleData`
291 * object of the current axis.
293 void initAxisUsageList(const Date
& rNullDate
);
296 * Perform automatic axis scaling and determine the amount and spacing of
297 * increments. It assumes that the caller has determined the size of the
298 * largest axis label text object prior to calling this method.
300 * The new axis scaling data will be stored in the VCoordinateSystem
301 * objects. The label alignment direction for each axis will also get
302 * determined during this process, and stored in VAxis.
304 * This method is invoked by `ChartView::impl_createDiagramAndContent`
305 * soon after `initAxisUsageList`.
306 * It initializes explicit scale and increment objects for all coordinate
307 * systems in `m_rVCooSysList`.
308 * This action is achieved by iterating on the `m_aAxisUsageList` container,
309 * and performing 3 steps:
310 * 1- call `VCoordinateSystem::prepareAutomaticAxisScaling` for setting
311 * scaling parameters of the `aAutoScaling` member (a `ScaleAutomatism`
312 * object) for the current `AxisUsage` instance
313 * (see `VCoordinateSystem::prepareAutomaticAxisScaling`);
314 * 2- calculate the explicit scale and increment objects
315 * (see ScaleAutomatism::calculateExplicitScaleAndIncrement);
316 * 3- set the explicit scale and increment objects for each coordinate
319 void doAutoScaling( ChartModel
& rModel
);
322 * After auto-scaling is performed, call this method to set the explicit
323 * scaling and increment data to all relevant VAxis objects.
325 void updateScalesAndIncrementsOnAxes();
328 * After auto-scaling is performed, call this method to set the explicit
329 * scaling data to all the plotters.
331 void setScalesFromCooSysToPlotter();
333 void setNumberFormatsFromAxes();
334 drawing::Direction3D
getPreferredAspectRatio();
336 SeriesPlottersType
& getSeriesPlotterList() { return m_aSeriesPlotterList
; }
337 std::vector
< VCoordinateSystem
* >& getCooSysList() { return m_rVCooSysList
; }
338 std::vector
< LegendEntryProvider
* > getLegendEntryProviderList();
340 void AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel
& rModel
);
342 bool isCategoryPositionShifted(
343 const chart2::ScaleData
& rSourceScale
, bool bHasComplexCategories
) const;
346 /** A vector of series plotters.
348 SeriesPlottersType m_aSeriesPlotterList
;
350 /** A vector of coordinate systems.
352 std::vector
< VCoordinateSystem
* >& m_rVCooSysList
;
354 /** A map whose key is a `XAxis` interface and the related value is
355 * an object of `AxisUsage` type.
357 ::std::map
< uno::Reference
< XAxis
>, AxisUsage
> m_aAxisUsageList
;
360 * Max axis index of all dimensions. Currently this can be either 0 or 1
361 * since we only support primary and secondary axes per dimension. The
362 * value of 0 means all dimensions have only primary axis, while 1 means
363 * at least one dimension has a secondary axis.
365 sal_Int32 m_nMaxAxisIndex
;
367 bool m_bChartTypeUsesShiftedCategoryPositionPerDefault
;
368 sal_Int32 m_nDefaultDateNumberFormat
;
371 SeriesPlotterContainer::SeriesPlotterContainer( std::vector
< VCoordinateSystem
* >& rVCooSysList
)
372 : m_rVCooSysList( rVCooSysList
)
374 , m_bChartTypeUsesShiftedCategoryPositionPerDefault(false)
375 , m_nDefaultDateNumberFormat(0)
379 SeriesPlotterContainer::~SeriesPlotterContainer()
381 // - remove plotter from coordinatesystems
382 for( size_t nC
=0; nC
< m_rVCooSysList
.size(); nC
++)
383 m_rVCooSysList
[nC
]->clearMinimumAndMaximumSupplierList();
386 std::vector
< LegendEntryProvider
* > SeriesPlotterContainer::getLegendEntryProviderList()
388 std::vector
< LegendEntryProvider
* > aRet( m_aSeriesPlotterList
.size() );
389 SeriesPlottersType::iterator aPlotterIter
= m_aSeriesPlotterList
.begin();
390 const SeriesPlottersType::iterator aPlotterEnd
= m_aSeriesPlotterList
.end();
392 for( aPlotterIter
= m_aSeriesPlotterList
.begin(); aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
, nN
++ )
393 aRet
[nN
] = &(*aPlotterIter
);
397 VCoordinateSystem
* findInCooSysList( const std::vector
< VCoordinateSystem
* >& rVCooSysList
398 , const uno::Reference
< XCoordinateSystem
>& xCooSys
)
400 for( size_t nC
=0; nC
< rVCooSysList
.size(); nC
++)
402 VCoordinateSystem
* pVCooSys
= rVCooSysList
[nC
];
403 if(pVCooSys
->getModel()==xCooSys
)
409 VCoordinateSystem
* lcl_getCooSysForPlotter( const std::vector
< VCoordinateSystem
* >& rVCooSysList
, MinimumAndMaximumSupplier
* pMinimumAndMaximumSupplier
)
411 if(!pMinimumAndMaximumSupplier
)
413 for( size_t nC
=0; nC
< rVCooSysList
.size(); nC
++)
415 VCoordinateSystem
* pVCooSys
= rVCooSysList
[nC
];
416 if(pVCooSys
->hasMinimumAndMaximumSupplier( pMinimumAndMaximumSupplier
))
422 VCoordinateSystem
* addCooSysToList( std::vector
< VCoordinateSystem
* >& rVCooSysList
423 , const uno::Reference
< XCoordinateSystem
>& xCooSys
424 , ChartModel
& rChartModel
)
426 VCoordinateSystem
* pVCooSys
= findInCooSysList( rVCooSysList
, xCooSys
);
429 pVCooSys
= VCoordinateSystem::createCoordinateSystem(xCooSys
);
432 OUString
aCooSysParticle( ObjectIdentifier::createParticleForCoordinateSystem( xCooSys
, rChartModel
) );
433 pVCooSys
->setParticle(aCooSysParticle
);
435 pVCooSys
->setExplicitCategoriesProvider( new ExplicitCategoriesProvider(xCooSys
, rChartModel
) );
437 rVCooSysList
.push_back( pVCooSys
);
443 void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(
444 ChartModel
& rChartModel
)
446 sal_Int32 nDiagramIndex
= 0;//todo if more than one diagram is supported
447 uno::Reference
< XDiagram
> xDiagram( rChartModel
.getFirstDiagram() );
451 uno::Reference
< util::XNumberFormatsSupplier
> xNumberFormatsSupplier( static_cast< ::cppu::OWeakObject
* >( &rChartModel
), uno::UNO_QUERY
);
452 if( rChartModel
.hasInternalDataProvider() && DiagramHelper::isSupportingDateAxis( xDiagram
) )
453 m_nDefaultDateNumberFormat
=DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
455 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
458 //@todo handle mixed dimension
462 bool bSortByXValues
= false;
463 bool bConnectBars
= false;
464 bool bGroupBarsPerAxis
= true;
465 bool bIncludeHiddenCells
= true;
466 sal_Int32 nStartingAngle
= 90;
467 sal_Int32 n3DRelativeHeight
= 100;
470 uno::Reference
< beans::XPropertySet
> xDiaProp( xDiagram
, uno::UNO_QUERY_THROW
);
471 xDiaProp
->getPropertyValue(CHART_UNONAME_SORT_BY_XVALUES
) >>= bSortByXValues
;
472 xDiaProp
->getPropertyValue( "ConnectBars" ) >>= bConnectBars
;
473 xDiaProp
->getPropertyValue( "GroupBarsPerAxis" ) >>= bGroupBarsPerAxis
;
474 xDiaProp
->getPropertyValue( "IncludeHiddenCells" ) >>= bIncludeHiddenCells
;
475 xDiaProp
->getPropertyValue( "StartingAngle" ) >>= nStartingAngle
;
477 if (nDimensionCount
== 3)
479 xDiaProp
->getPropertyValue( "3DRelativeHeight" ) >>= n3DRelativeHeight
;
482 catch( const uno::Exception
& ex
)
484 ASSERT_EXCEPTION( ex
);
487 //prepare for autoscaling and shape creation
488 // - create plotter for charttypes (for each first scale group at each plotter, as they are independent)
489 // - add series to plotter (thus each charttype can provide minimum and maximum values for autoscaling)
490 // - add plotter to coordinate systems
492 //iterate through all coordinate systems
493 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
494 OSL_ASSERT( xCooSysContainer
.is());
495 if( !xCooSysContainer
.is())
497 uno::Reference
< XColorScheme
> xColorScheme( xDiagram
->getDefaultColorScheme());
498 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
499 sal_Int32 nGlobalSeriesIndex
= 0;//for automatic symbols
500 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
502 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSysList
[nCS
] );
503 VCoordinateSystem
* pVCooSys
= addCooSysToList(m_rVCooSysList
,xCooSys
,rChartModel
);
505 //iterate through all chart types in the current coordinate system
506 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
507 OSL_ASSERT( xChartTypeContainer
.is());
508 if( !xChartTypeContainer
.is() )
510 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
511 for( sal_Int32 nT
= 0; nT
< aChartTypeList
.getLength(); ++nT
)
513 uno::Reference
< XChartType
> xChartType( aChartTypeList
[nT
] );
514 if(3 == nDimensionCount
&& xChartType
->getChartType().equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE
))
516 uno::Reference
< beans::XPropertySet
> xPropertySet( xChartType
, uno::UNO_QUERY
);
517 if (xPropertySet
.is())
521 sal_Int32
n3DRelativeHeightOldValue(100);
522 uno::Any aAny
= xPropertySet
->getPropertyValue( "3DRelativeHeight" );
523 aAny
>>= n3DRelativeHeightOldValue
;
524 if (n3DRelativeHeightOldValue
!= n3DRelativeHeight
)
525 xPropertySet
->setPropertyValue( "3DRelativeHeight", uno::makeAny(n3DRelativeHeight
) );
527 catch (const uno::Exception
&) { }
532 m_bChartTypeUsesShiftedCategoryPositionPerDefault
= ChartTypeHelper::shiftCategoryPosAtXAxisPerDefault( xChartType
);
534 bool bExcludingPositioning
= DiagramPositioningMode_EXCLUDING
== DiagramHelper::getDiagramPositioningMode( xDiagram
);
535 VSeriesPlotter
* pPlotter
= VSeriesPlotter::createSeriesPlotter( xChartType
, nDimensionCount
, bExcludingPositioning
);
539 m_aSeriesPlotterList
.push_back( pPlotter
);
540 pPlotter
->setNumberFormatsSupplier( xNumberFormatsSupplier
);
541 pPlotter
->setColorScheme( xColorScheme
);
543 pPlotter
->setExplicitCategoriesProvider( pVCooSys
->getExplicitCategoriesProvider() );
544 sal_Int32 nMissingValueTreatment
= DiagramHelper::getCorrectedMissingValueTreatment( xDiagram
, xChartType
);
547 pVCooSys
->addMinimumAndMaximumSupplier(pPlotter
);
549 uno::Reference
< XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY
);
550 OSL_ASSERT( xDataSeriesContainer
.is());
551 if( !xDataSeriesContainer
.is() )
557 uno::Sequence
< uno::Reference
< XDataSeries
> > aSeriesList( xDataSeriesContainer
->getDataSeries() );
558 for( sal_Int32 nS
= 0; nS
< aSeriesList
.getLength(); ++nS
)
560 uno::Reference
< XDataSeries
> xDataSeries( aSeriesList
[nS
], uno::UNO_QUERY
);
561 if(!xDataSeries
.is())
563 if( !bIncludeHiddenCells
&& !DataSeriesHelper::hasUnhiddenData(xDataSeries
) )
566 VDataSeries
* pSeries
= new VDataSeries( xDataSeries
);
568 pSeries
->setGlobalSeriesIndex(nGlobalSeriesIndex
);
569 nGlobalSeriesIndex
++;
572 pSeries
->doSortByXValues();
574 pSeries
->setConnectBars( bConnectBars
);
575 pSeries
->setGroupBarsPerAxis( bGroupBarsPerAxis
);
576 pSeries
->setStartingAngle( nStartingAngle
);
578 pSeries
->setMissingValueTreatment( nMissingValueTreatment
);
580 OUString
aSeriesParticle( ObjectIdentifier::createParticleForSeries( nDiagramIndex
, nCS
, nT
, nS
) );
581 pSeries
->setParticle(aSeriesParticle
);
583 OUString
aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType
) );
584 pSeries
->setRoleOfSequenceForDataLabelNumberFormatDetection(aRole
);
586 //ignore secondary axis for charttypes that do not suppoert them
587 if( pSeries
->getAttachedAxisIndex() != MAIN_AXIS_INDEX
&&
588 !ChartTypeHelper::isSupportingSecondaryAxis( xChartType
, nDimensionCount
, 1 ) )
590 pSeries
->setAttachedAxisIndex(MAIN_AXIS_INDEX
);
593 StackingDirection eDirection
= pSeries
->getStackingDirection();
596 case StackingDirection_NO_STACKING
:
601 case StackingDirection_Y_STACKING
:
608 case StackingDirection_Z_STACKING
:
609 zSlot
++; xSlot
=-1; ySlot
=-1;
612 // UNO enums have one additional auto-generated case
615 pPlotter
->addSeries( pSeries
, zSlot
, xSlot
, ySlot
);
620 //transport seriesnames to the coordinatesystems if needed
621 if( !m_aSeriesPlotterList
.empty() )
623 uno::Sequence
< OUString
> aSeriesNames
;
624 bool bSeriesNamesInitialized
= false;
625 for( size_t nC
=0; nC
< m_rVCooSysList
.size(); nC
++)
627 VCoordinateSystem
* pVCooSys
= m_rVCooSysList
[nC
];
630 if( pVCooSys
->needSeriesNamesForAxis() )
632 if(!bSeriesNamesInitialized
)
634 VSeriesPlotter
* pSeriesPlotter
= &m_aSeriesPlotterList
[0];
636 aSeriesNames
= pSeriesPlotter
->getSeriesNames();
637 bSeriesNamesInitialized
= true;
639 pVCooSys
->setSeriesNamesForAxis( aSeriesNames
);
645 bool SeriesPlotterContainer::isCategoryPositionShifted(
646 const chart2::ScaleData
& rSourceScale
, bool bHasComplexCategories
) const
648 if (rSourceScale
.AxisType
== AxisType::CATEGORY
&& m_bChartTypeUsesShiftedCategoryPositionPerDefault
)
651 if (rSourceScale
.AxisType
==AxisType::CATEGORY
&& bHasComplexCategories
)
654 if (rSourceScale
.AxisType
== AxisType::DATE
)
657 if (rSourceScale
.AxisType
== AxisType::SERIES
)
663 void SeriesPlotterContainer::initAxisUsageList(const Date
& rNullDate
)
665 m_aAxisUsageList
.clear();
667 // Loop through coordinate systems in the diagram (though for now
668 // there should only be one coordinate system per diagram).
669 for (size_t i
= 0, n
= m_rVCooSysList
.size(); i
< n
; ++i
)
671 VCoordinateSystem
* pVCooSys
= m_rVCooSysList
[i
];
672 uno::Reference
<XCoordinateSystem
> xCooSys
= pVCooSys
->getModel();
673 sal_Int32 nDimCount
= xCooSys
->getDimension();
675 for (sal_Int32 nDimIndex
= 0; nDimIndex
< nDimCount
; ++nDimIndex
)
677 bool bDateAxisAllowed
= ChartTypeHelper::isSupportingDateAxis(
678 AxisHelper::getChartTypeByIndex(xCooSys
, 0), nDimCount
, nDimIndex
);
680 // Each dimension may have primary and secondary axes.
681 const sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimIndex
);
682 for (sal_Int32 nAxisIndex
= 0; nAxisIndex
<= nMaxAxisIndex
; ++nAxisIndex
)
684 uno::Reference
<XAxis
> xAxis
= xCooSys
->getAxisByDimension(nDimIndex
, nAxisIndex
);
689 if (m_aAxisUsageList
.find(xAxis
) == m_aAxisUsageList
.end())
691 // Create axis usage object for this axis.
693 chart2::ScaleData aSourceScale
= xAxis
->getScaleData();
694 ExplicitCategoriesProvider
* pCatProvider
= pVCooSys
->getExplicitCategoriesProvider();
696 AxisHelper::checkDateAxis( aSourceScale
, pCatProvider
, bDateAxisAllowed
);
698 bool bHasComplexCat
= pCatProvider
&& pCatProvider
->hasComplexCategories();
699 aSourceScale
.ShiftedCategoryPosition
= isCategoryPositionShifted(aSourceScale
, bHasComplexCat
);
701 m_aAxisUsageList
[xAxis
].aAutoScaling
= ScaleAutomatism(aSourceScale
, rNullDate
);
704 AxisUsage
& rAxisUsage
= m_aAxisUsageList
[xAxis
];
705 rAxisUsage
.addCoordinateSystem(pVCooSys
, nDimIndex
, nAxisIndex
);
710 // Determine the highest axis index of all dimensions.
711 ::std::map
< uno::Reference
< XAxis
>, AxisUsage
>::iterator aAxisIter
= m_aAxisUsageList
.begin();
712 const ::std::map
< uno::Reference
< XAxis
>, AxisUsage
>::const_iterator aAxisEndIter
= m_aAxisUsageList
.end();
714 for (size_t i
= 0, n
= m_rVCooSysList
.size(); i
< n
; ++i
)
716 VCoordinateSystem
* pVCooSys
= m_rVCooSysList
[i
];
717 uno::Reference
<XCoordinateSystem
> xCooSys
= pVCooSys
->getModel();
718 sal_Int32 nDimCount
= xCooSys
->getDimension();
720 for (sal_Int32 nDimIndex
= 0; nDimIndex
< nDimCount
; ++nDimIndex
)
722 for (aAxisIter
= m_aAxisUsageList
.begin(); aAxisIter
!= aAxisEndIter
; ++aAxisIter
)
724 sal_Int32 nLocalMax
= aAxisIter
->second
.getMaxAxisIndexForDimension(nDimIndex
);
725 if (m_nMaxAxisIndex
< nLocalMax
)
726 m_nMaxAxisIndex
= nLocalMax
;
732 void SeriesPlotterContainer::setScalesFromCooSysToPlotter()
734 //set scales to plotter to enable them to provide the preferred scene AspectRatio
735 SeriesPlottersType::iterator aPlotterIter
= m_aSeriesPlotterList
.begin();
736 const SeriesPlottersType::iterator aPlotterEnd
= m_aSeriesPlotterList
.end();
737 for( aPlotterIter
= m_aSeriesPlotterList
.begin(); aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
)
739 VSeriesPlotter
* pSeriesPlotter
= &(*aPlotterIter
);
740 VCoordinateSystem
* pVCooSys
= lcl_getCooSysForPlotter( m_rVCooSysList
, pSeriesPlotter
);
743 pSeriesPlotter
->setScales( pVCooSys
->getExplicitScales(0,0), pVCooSys
->getPropertySwapXAndYAxis() );
744 sal_Int32 nMaxAxisIndex
= pVCooSys
->getMaximumAxisIndexByDimension(1);//only additional value axis are relevant for series plotter
745 for( sal_Int32 nI
=1; nI
<=nMaxAxisIndex
; nI
++ )
746 pSeriesPlotter
->addSecondaryValueScale( pVCooSys
->getExplicitScale(1,nI
), nI
);
751 void SeriesPlotterContainer::setNumberFormatsFromAxes()
753 //set numberformats to plotter to enable them to display the data labels in the numberformat of the axis
754 SeriesPlottersType::iterator aPlotterIter
= m_aSeriesPlotterList
.begin();
755 const SeriesPlottersType::iterator aPlotterEnd
= m_aSeriesPlotterList
.end();
756 for( aPlotterIter
= m_aSeriesPlotterList
.begin(); aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
)
758 VSeriesPlotter
* pSeriesPlotter
= &(*aPlotterIter
);
759 VCoordinateSystem
* pVCooSys
= lcl_getCooSysForPlotter( m_rVCooSysList
, pSeriesPlotter
);
762 AxesNumberFormats aAxesNumberFormats
;
763 uno::Reference
< XCoordinateSystem
> xCooSys
= pVCooSys
->getModel();
764 sal_Int32 nDimensionCount
= xCooSys
->getDimension();
765 for(sal_Int32 nDimensionIndex
=0; nDimensionIndex
<nDimensionCount
; ++nDimensionIndex
)
767 const sal_Int32 nMaximumAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
768 for(sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaximumAxisIndex
; ++nAxisIndex
)
772 Reference
< beans::XPropertySet
> xAxisProp( xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
), uno::UNO_QUERY
);
775 sal_Int32
nNumberFormatKey(0);
776 if( xAxisProp
->getPropertyValue(CHART_UNONAME_NUMFMT
) >>= nNumberFormatKey
)
778 aAxesNumberFormats
.setFormat( nNumberFormatKey
, nDimensionIndex
, nAxisIndex
);
780 else if( nDimensionIndex
==0 )
782 //provide a default date format for date axis with own data
783 aAxesNumberFormats
.setFormat( m_nDefaultDateNumberFormat
, nDimensionIndex
, nAxisIndex
);
787 catch( const lang::IndexOutOfBoundsException
& e
)
789 ASSERT_EXCEPTION( e
);
793 pSeriesPlotter
->setAxesNumberFormats( aAxesNumberFormats
);
798 void SeriesPlotterContainer::updateScalesAndIncrementsOnAxes()
800 for( size_t nC
=0; nC
< m_rVCooSysList
.size(); nC
++)
801 m_rVCooSysList
[nC
]->updateScalesAndIncrementsOnAxes();
804 void SeriesPlotterContainer::doAutoScaling( ChartModel
& rChartModel
)
806 if (m_aSeriesPlotterList
.empty() || m_aAxisUsageList
.empty())
807 // We need these two containers populated to do auto-scaling. Bail out.
810 ::std::map
< uno::Reference
< XAxis
>, AxisUsage
>::iterator aAxisIter
= m_aAxisUsageList
.begin();
811 const ::std::map
< uno::Reference
< XAxis
>, AxisUsage
>::const_iterator aAxisEndIter
= m_aAxisUsageList
.end();
813 //iterate over the main scales first than secondary axis
814 for (sal_Int32 nAxisIndex
= 0; nAxisIndex
<= m_nMaxAxisIndex
; ++nAxisIndex
)
816 // - first do autoscale for all x and z scales (because they are treated independent)
817 for( aAxisIter
= m_aAxisUsageList
.begin(); aAxisIter
!= aAxisEndIter
; ++aAxisIter
)
819 AxisUsage
& rAxisUsage
= (*aAxisIter
).second
;
821 rAxisUsage
.prepareAutomaticAxisScaling(rAxisUsage
.aAutoScaling
, 0, nAxisIndex
);
822 rAxisUsage
.prepareAutomaticAxisScaling(rAxisUsage
.aAutoScaling
, 2, nAxisIndex
);
824 ExplicitScaleData aExplicitScale
;
825 ExplicitIncrementData aExplicitIncrement
;
826 rAxisUsage
.aAutoScaling
.calculateExplicitScaleAndIncrement( aExplicitScale
, aExplicitIncrement
);
828 rAxisUsage
.setExplicitScaleAndIncrement(0, nAxisIndex
, aExplicitScale
, aExplicitIncrement
);
829 rAxisUsage
.setExplicitScaleAndIncrement(2, nAxisIndex
, aExplicitScale
, aExplicitIncrement
);
832 // - second do autoscale for the dependent y scales (the coordinate systems are prepared with x and z scales already )
833 for( aAxisIter
= m_aAxisUsageList
.begin(); aAxisIter
!= aAxisEndIter
; ++aAxisIter
)
835 AxisUsage
& rAxisUsage
= (*aAxisIter
).second
;
837 rAxisUsage
.prepareAutomaticAxisScaling(rAxisUsage
.aAutoScaling
, 1, nAxisIndex
);
839 ExplicitScaleData aExplicitScale
;
840 ExplicitIncrementData aExplicitIncrement
;
841 rAxisUsage
.aAutoScaling
.calculateExplicitScaleAndIncrement( aExplicitScale
, aExplicitIncrement
);
843 rAxisUsage
.setExplicitScaleAndIncrement(0, nAxisIndex
, aExplicitScale
, aExplicitIncrement
);
844 rAxisUsage
.setExplicitScaleAndIncrement(1, nAxisIndex
, aExplicitScale
, aExplicitIncrement
);
845 rAxisUsage
.setExplicitScaleAndIncrement(2, nAxisIndex
, aExplicitScale
, aExplicitIncrement
);
848 AdaptScaleOfYAxisWithoutAttachedSeries( rChartModel
);
851 void SeriesPlotterContainer::AdaptScaleOfYAxisWithoutAttachedSeries( ChartModel
& rModel
)
855 ::std::map
< uno::Reference
< XAxis
>, AxisUsage
>::iterator aAxisIter
= m_aAxisUsageList
.begin();
856 const ::std::map
< uno::Reference
< XAxis
>, AxisUsage
>::const_iterator aAxisEndIter
= m_aAxisUsageList
.end();
858 for( sal_Int32 nAxisIndex
=0; nAxisIndex
<=m_nMaxAxisIndex
; nAxisIndex
++ )
860 for( aAxisIter
= m_aAxisUsageList
.begin(); aAxisIter
!= aAxisEndIter
; ++aAxisIter
)
862 AxisUsage
& rAxisUsage
= (*aAxisIter
).second
;
863 ::std::vector
< VCoordinateSystem
* > aVCooSysList_Y
= rAxisUsage
.getCoordinateSystems( 1, nAxisIndex
);
864 if( !aVCooSysList_Y
.size() )
867 uno::Reference
< XDiagram
> xDiagram( rModel
.getFirstDiagram() );
871 bool bSeriesAttachedToThisAxis
= false;
872 sal_Int32 nAttachedAxisIndex
= -1;
874 ::std::vector
< Reference
< XDataSeries
> > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
875 ::std::vector
< Reference
< XDataSeries
> >::const_iterator aIter
= aSeriesVector
.begin();
876 for( ; aIter
!= aSeriesVector
.end(); ++aIter
)
878 sal_Int32 nCurrentIndex
= DataSeriesHelper::getAttachedAxisIndex( *aIter
);
879 if( nAxisIndex
== nCurrentIndex
)
881 bSeriesAttachedToThisAxis
= true;
884 else if( nAttachedAxisIndex
<0 || nAttachedAxisIndex
>nCurrentIndex
)
885 nAttachedAxisIndex
=nCurrentIndex
;
889 if (bSeriesAttachedToThisAxis
|| nAttachedAxisIndex
< 0)
892 for( size_t nC
= 0; nC
< aVCooSysList_Y
.size(); ++nC
)
894 aVCooSysList_Y
[nC
]->prepareAutomaticAxisScaling( rAxisUsage
.aAutoScaling
, 1, nAttachedAxisIndex
);
896 ExplicitScaleData aExplicitScaleSource
= aVCooSysList_Y
[nC
]->getExplicitScale( 1,nAttachedAxisIndex
);
897 ExplicitIncrementData aExplicitIncrementSource
= aVCooSysList_Y
[nC
]->getExplicitIncrement( 1,nAttachedAxisIndex
);
899 ExplicitScaleData aExplicitScaleDest
= aVCooSysList_Y
[nC
]->getExplicitScale( 1,nAxisIndex
);;
900 ExplicitIncrementData aExplicitIncrementDest
= aVCooSysList_Y
[nC
]->getExplicitIncrement( 1,nAxisIndex
);;
902 aExplicitScaleDest
.Orientation
= aExplicitScaleSource
.Orientation
;
903 aExplicitScaleDest
.Scaling
= aExplicitScaleSource
.Scaling
;
904 aExplicitScaleDest
.AxisType
= aExplicitScaleSource
.AxisType
;
906 aExplicitIncrementDest
.BaseValue
= aExplicitIncrementSource
.BaseValue
;
908 ScaleData
aScale( rAxisUsage
.aAutoScaling
.getScale() );
909 if( !aScale
.Minimum
.hasValue() )
911 bool bNewMinOK
= true;
913 if( aScale
.Maximum
>>= fMax
)
914 bNewMinOK
= (aExplicitScaleSource
.Minimum
<= fMax
);
916 aExplicitScaleDest
.Minimum
= aExplicitScaleSource
.Minimum
;
919 aExplicitIncrementDest
.BaseValue
= aExplicitScaleDest
.Minimum
;
921 if( !aScale
.Maximum
.hasValue() )
923 bool bNewMaxOK
= true;
925 if( aScale
.Minimum
>>= fMin
)
926 bNewMaxOK
= (fMin
<= aExplicitScaleSource
.Maximum
);
928 aExplicitScaleDest
.Maximum
= aExplicitScaleSource
.Maximum
;
930 if( !aScale
.Origin
.hasValue() )
931 aExplicitScaleDest
.Origin
= aExplicitScaleSource
.Origin
;
933 if( !aScale
.IncrementData
.Distance
.hasValue() )
934 aExplicitIncrementDest
.Distance
= aExplicitIncrementSource
.Distance
;
936 bool bAutoMinorInterval
= true;
937 if( aScale
.IncrementData
.SubIncrements
.getLength() )
938 bAutoMinorInterval
= !( aScale
.IncrementData
.SubIncrements
[0].IntervalCount
.hasValue() );
939 if( bAutoMinorInterval
)
941 if( !aExplicitIncrementDest
.SubIncrements
.empty() && !aExplicitIncrementSource
.SubIncrements
.empty() )
942 aExplicitIncrementDest
.SubIncrements
[0].IntervalCount
=
943 aExplicitIncrementSource
.SubIncrements
[0].IntervalCount
;
946 aVCooSysList_Y
[nC
]->setExplicitScaleAndIncrement( 1, nAxisIndex
, aExplicitScaleDest
, aExplicitIncrementDest
);
951 if( AxisHelper::isAxisPositioningEnabled() )
953 //correct origin for y main axis (the origin is where the other main axis crosses)
954 sal_Int32 nAxisIndex
=0;
955 sal_Int32 nDimensionIndex
=1;
956 for( aAxisIter
= m_aAxisUsageList
.begin(); aAxisIter
!= aAxisEndIter
; ++aAxisIter
)
958 AxisUsage
& rAxisUsage
= (*aAxisIter
).second
;
959 ::std::vector
< VCoordinateSystem
* > aVCooSysList
= rAxisUsage
.getCoordinateSystems(nDimensionIndex
,nAxisIndex
);
961 for( nC
=0; nC
< aVCooSysList
.size(); nC
++)
963 ExplicitScaleData
aExplicitScale( aVCooSysList
[nC
]->getExplicitScale( nDimensionIndex
, nAxisIndex
) );
964 ExplicitIncrementData
aExplicitIncrement( aVCooSysList
[nC
]->getExplicitIncrement( nDimensionIndex
, nAxisIndex
) );
966 Reference
< chart2::XCoordinateSystem
> xCooSys( aVCooSysList
[nC
]->getModel() );
967 Reference
< XAxis
> xAxis( xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
968 Reference
< beans::XPropertySet
> xCrossingMainAxis( AxisHelper::getCrossingMainAxis( xAxis
, xCooSys
), uno::UNO_QUERY
);
970 ::com::sun::star::chart::ChartAxisPosition
eCrossingMainAxisPos( ::com::sun::star::chart::ChartAxisPosition_ZERO
);
971 if( xCrossingMainAxis
.is() )
973 xCrossingMainAxis
->getPropertyValue("CrossoverPosition") >>= eCrossingMainAxisPos
;
974 if( ::com::sun::star::chart::ChartAxisPosition_VALUE
== eCrossingMainAxisPos
)
977 xCrossingMainAxis
->getPropertyValue("CrossoverValue") >>= fValue
;
978 aExplicitScale
.Origin
= fValue
;
980 else if( ::com::sun::star::chart::ChartAxisPosition_ZERO
== eCrossingMainAxisPos
)
981 aExplicitScale
.Origin
= 0.0;
982 else if( ::com::sun::star::chart::ChartAxisPosition_START
== eCrossingMainAxisPos
)
983 aExplicitScale
.Origin
= aExplicitScale
.Minimum
;
984 else if( ::com::sun::star::chart::ChartAxisPosition_END
== eCrossingMainAxisPos
)
985 aExplicitScale
.Origin
= aExplicitScale
.Maximum
;
988 aVCooSysList
[nC
]->setExplicitScaleAndIncrement( nDimensionIndex
, nAxisIndex
, aExplicitScale
, aExplicitIncrement
);
994 drawing::Direction3D
SeriesPlotterContainer::getPreferredAspectRatio()
996 drawing::Direction3D
aPreferredAspectRatio(1.0,1.0,1.0);
998 sal_Int32 nPlotterCount
=0;
999 //get a list of all preferred aspect ratios and combine them
1000 //first with special demands wins (less or equal zero <-> arbitrary)
1002 fx
= fy
= fz
= -1.0;
1003 SeriesPlottersType::const_iterator aPlotterIter
= m_aSeriesPlotterList
.begin();
1004 const SeriesPlottersType::const_iterator aPlotterEnd
= m_aSeriesPlotterList
.end();
1005 for( aPlotterIter
= m_aSeriesPlotterList
.begin(), nPlotterCount
=0
1006 ; aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
, ++nPlotterCount
)
1008 drawing::Direction3D
aSingleRatio( aPlotterIter
->getPreferredDiagramAspectRatio() );
1009 if( fx
<0 && aSingleRatio
.DirectionX
>0 )
1010 fx
= aSingleRatio
.DirectionX
;
1012 if( fy
<0 && aSingleRatio
.DirectionY
>0 )
1014 if( fx
>0 && aSingleRatio
.DirectionX
>0 )
1015 fy
= fx
*aSingleRatio
.DirectionY
/aSingleRatio
.DirectionX
;
1016 else if( fz
>0 && aSingleRatio
.DirectionZ
>0 )
1017 fy
= fz
*aSingleRatio
.DirectionY
/aSingleRatio
.DirectionZ
;
1019 fy
= aSingleRatio
.DirectionY
;
1022 if( fz
<0 && aSingleRatio
.DirectionZ
>0 )
1024 if( fx
>0 && aSingleRatio
.DirectionX
>0 )
1025 fz
= fx
*aSingleRatio
.DirectionZ
/aSingleRatio
.DirectionX
;
1026 else if( fy
>0 && aSingleRatio
.DirectionY
>0 )
1027 fz
= fy
*aSingleRatio
.DirectionZ
/aSingleRatio
.DirectionY
;
1029 fz
= aSingleRatio
.DirectionZ
;
1032 if( fx
>0 && fy
>0 && fz
>0 )
1035 aPreferredAspectRatio
= drawing::Direction3D(fx
, fy
, fz
);
1036 return aPreferredAspectRatio
;
1041 struct CreateShapeParam2D
1043 css::awt::Rectangle maRemainingSpace
;
1045 boost::shared_ptr
<SeriesPlotterContainer
> mpSeriesPlotterContainer
;
1047 boost::shared_ptr
<VTitle
> mpVTitleX
;
1048 boost::shared_ptr
<VTitle
> mpVTitleY
;
1049 boost::shared_ptr
<VTitle
> mpVTitleZ
;
1051 boost::shared_ptr
<VTitle
> mpVTitleSecondX
;
1052 boost::shared_ptr
<VTitle
> mpVTitleSecondY
;
1054 css::uno::Reference
<css::drawing::XShape
> mxMarkHandles
;
1055 css::uno::Reference
<css::drawing::XShape
> mxPlotAreaWithAxes
;
1057 css::uno::Reference
<css::drawing::XShapes
> mxDiagramWithAxesShapes
;
1059 bool mbAutoPosTitleX
;
1060 bool mbAutoPosTitleY
;
1061 bool mbAutoPosTitleZ
;
1063 bool mbAutoPosSecondTitleX
;
1064 bool mbAutoPosSecondTitleY
;
1066 bool mbUseFixedInnerSize
;
1068 CreateShapeParam2D() :
1069 mbAutoPosTitleX(true),
1070 mbAutoPosTitleY(true),
1071 mbAutoPosTitleZ(true),
1072 mbAutoPosSecondTitleX(true),
1073 mbAutoPosSecondTitleY(true),
1074 mbUseFixedInnerSize(false) {}
1077 class GL2DRenderer
: public IRenderer
1080 GL2DRenderer(ChartView
* pView
);
1081 virtual ~GL2DRenderer();
1083 virtual void update() SAL_OVERRIDE
;
1084 virtual void clickedAt(const Point
& rPos
, sal_uInt16 nButton
) SAL_OVERRIDE
;
1085 virtual void mouseDragMove(const Point
& rBegin
, const Point
& rEnd
, sal_uInt16 nButton
) SAL_OVERRIDE
;
1086 virtual void scroll(long nDelta
) SAL_OVERRIDE
;
1087 virtual void contextDestroyed() SAL_OVERRIDE
;
1089 const OpenGLWindow
* getOpenGLWindow() const;
1090 void updateOpenGLWindow();
1093 bool mbContextDestroyed
;
1094 VclPtr
<OpenGLWindow
> mpWindow
;
1097 GL2DRenderer::GL2DRenderer(ChartView
* pView
):
1099 mbContextDestroyed(false),
1100 mpWindow(mpView
->mrChartModel
.getOpenGLWindow())
1104 GL2DRenderer::~GL2DRenderer()
1107 if(!mbContextDestroyed
&& mpWindow
)
1108 mpWindow
->setRenderer(NULL
);
1112 void GL2DRenderer::update()
1118 void GL2DRenderer::clickedAt(const Point
&, sal_uInt16
)
1122 void GL2DRenderer::mouseDragMove(const Point
& , const Point
& , sal_uInt16
)
1126 void GL2DRenderer::scroll(long )
1130 void GL2DRenderer::contextDestroyed()
1132 mbContextDestroyed
= true;
1135 const OpenGLWindow
* GL2DRenderer::getOpenGLWindow() const
1140 void GL2DRenderer::updateOpenGLWindow()
1142 if(mbContextDestroyed
)
1145 OpenGLWindow
* pWindow
= mpView
->mrChartModel
.getOpenGLWindow();
1146 if(pWindow
!= mpWindow
)
1150 mpWindow
->setRenderer(NULL
);
1155 pWindow
->setRenderer(this);
1161 const uno::Sequence
<sal_Int8
>& ExplicitValueProvider::getUnoTunnelId()
1163 return theExplicitValueProviderUnoTunnelId::get().getSeq();
1166 ExplicitValueProvider
* ExplicitValueProvider::getExplicitValueProvider(
1167 const Reference
< uno::XInterface
>& xChartView
)
1169 ExplicitValueProvider
* pExplicitValueProvider
=0;
1171 Reference
< lang::XUnoTunnel
> xTunnel( xChartView
, uno::UNO_QUERY
);
1174 pExplicitValueProvider
= reinterpret_cast<ExplicitValueProvider
*>(xTunnel
->getSomething(
1175 ExplicitValueProvider::getUnoTunnelId() ));
1177 return pExplicitValueProvider
;
1180 ChartView::ChartView(
1181 uno::Reference
<uno::XComponentContext
> const & xContext
,
1185 , mrChartModel(rModel
)
1188 , m_pDrawModelWrapper()
1189 , m_aListenerContainer( m_aMutex
)
1190 , m_bViewDirty(true)
1191 , m_bInViewUpdate(false)
1192 , m_bViewUpdatePending(false)
1193 , m_bRefreshAddIn(true)
1194 , m_aPageResolution(1000,1000)
1195 , m_bPointsWereSkipped(false)
1196 , m_nScaleXNumerator(1)
1197 , m_nScaleXDenominator(1)
1198 , m_nScaleYNumerator(1)
1199 , m_nScaleYDenominator(1)
1200 , m_bSdrViewIsInEditMode(false)
1201 , m_aResultingDiagramRectangleExcludingAxes(0,0,0,0)
1202 , mp2DRenderer(new GL2DRenderer(this))
1207 void ChartView::init()
1209 if( !m_pDrawModelWrapper
.get() )
1211 SolarMutexGuard aSolarGuard
;
1212 m_pDrawModelWrapper
= ::boost::shared_ptr
< DrawModelWrapper
>( new DrawModelWrapper( m_xCC
) );
1213 m_xShapeFactory
= m_pDrawModelWrapper
->getShapeFactory();
1214 m_xDrawPage
= m_pDrawModelWrapper
->getMainDrawPage();
1215 StartListening( m_pDrawModelWrapper
->getSdrModel(), false /*bPreventDups*/ );
1219 void SAL_CALL
ChartView::initialize( const uno::Sequence
< uno::Any
>& )
1220 throw ( uno::Exception
, uno::RuntimeException
, std::exception
)
1225 ChartView::~ChartView()
1227 maTimeBased
.maTimer
.Stop();
1228 // #i120831#. In ChartView::initialize(), m_xShapeFactory is created from SdrModel::getUnoModel() and indirectly
1229 // from SfxBaseModel, it needs call dispose() to make sure SfxBaseModel object is freed correctly.
1230 uno::Reference
< lang::XComponent
> xComp( m_xShapeFactory
, uno::UNO_QUERY
);
1234 if( m_pDrawModelWrapper
.get() )
1236 SolarMutexGuard aSolarGuard
;
1237 EndListening( m_pDrawModelWrapper
->getSdrModel(), false /*bAllDups*/ );
1238 m_pDrawModelWrapper
.reset();
1241 impl_deleteCoordinateSystems();
1244 void ChartView::impl_deleteCoordinateSystems()
1246 //delete all coordinate systems
1247 ::std::vector
< VCoordinateSystem
* > aVectorToDeleteObjects
;
1248 ::std::swap( aVectorToDeleteObjects
, m_aVCooSysList
);//#i109770#
1249 ::std::vector
< VCoordinateSystem
* >::const_iterator aIter
= aVectorToDeleteObjects
.begin();
1250 const ::std::vector
< VCoordinateSystem
* >::const_iterator aEnd
= aVectorToDeleteObjects
.end();
1251 for( ; aIter
!= aEnd
; ++aIter
)
1255 aVectorToDeleteObjects
.clear();
1258 // datatransfer::XTransferable
1261 const OUString
lcl_aGDIMetaFileMIMEType(
1262 "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" );
1263 const OUString
lcl_aGDIMetaFileMIMETypeHighContrast(
1264 "application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" );
1265 } // anonymous namespace
1267 void ChartView::getMetaFile( const uno::Reference
< io::XOutputStream
>& xOutStream
1268 , bool bUseHighContrast
)
1270 if( !m_xDrawPage
.is() )
1273 // creating the graphic exporter
1274 uno::Reference
< drawing::XGraphicExportFilter
> xExporter
= drawing::GraphicExportFilter::create( m_xCC
);
1276 uno::Sequence
< beans::PropertyValue
> aProps(3);
1277 aProps
[0].Name
= "FilterName";
1278 aProps
[0].Value
<<= OUString("SVM");
1280 aProps
[1].Name
= "OutputStream";
1281 aProps
[1].Value
<<= xOutStream
;
1283 uno::Sequence
< beans::PropertyValue
> aFilterData(4);
1284 aFilterData
[0].Name
= "ExportOnlyBackground";
1285 aFilterData
[0].Value
<<= sal_False
;
1286 aFilterData
[1].Name
= "HighContrast";
1287 aFilterData
[1].Value
<<= bUseHighContrast
;
1289 aFilterData
[2].Name
= "Version";
1290 const sal_Int32 nVersion
= SOFFICE_FILEFORMAT_50
;
1291 aFilterData
[2].Value
<<= nVersion
;
1293 aFilterData
[3].Name
= "CurrentPage";
1294 aFilterData
[3].Value
<<= uno::Reference
< uno::XInterface
>( m_xDrawPage
, uno::UNO_QUERY
);
1296 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
1298 aFilterData
.realloc( aFilterData
.getLength()+4 );
1299 aFilterData
[4].Name
= "ScaleXNumerator";
1300 aFilterData
[4].Value
= uno::makeAny( m_nScaleXNumerator
);
1301 aFilterData
[5].Name
= "ScaleXDenominator";
1302 aFilterData
[5].Value
= uno::makeAny( m_nScaleXDenominator
);
1303 aFilterData
[6].Name
= "ScaleYNumerator";
1304 aFilterData
[6].Value
= uno::makeAny( m_nScaleYNumerator
);
1305 aFilterData
[7].Name
= "ScaleYDenominator";
1306 aFilterData
[7].Value
= uno::makeAny( m_nScaleYDenominator
);
1309 aProps
[2].Name
= "FilterData";
1310 aProps
[2].Value
<<= aFilterData
;
1312 xExporter
->setSourceDocument( uno::Reference
< lang::XComponent
>( m_xDrawPage
, uno::UNO_QUERY
) );
1313 if( xExporter
->filter( aProps
) )
1315 xOutStream
->flush();
1316 xOutStream
->closeOutput();
1317 uno::Reference
< io::XSeekable
> xSeekable( xOutStream
, uno::UNO_QUERY
);
1318 if( xSeekable
.is() )
1323 uno::Any SAL_CALL
ChartView::getTransferData( const datatransfer::DataFlavor
& aFlavor
)
1324 throw (datatransfer::UnsupportedFlavorException
, io::IOException
, uno::RuntimeException
, std::exception
)
1326 bool bHighContrastMetaFile( aFlavor
.MimeType
.equals(lcl_aGDIMetaFileMIMETypeHighContrast
));
1328 if( ! (bHighContrastMetaFile
|| aFlavor
.MimeType
.equals(lcl_aGDIMetaFileMIMEType
)) )
1333 SvMemoryStream
aStream( 1024, 1024 );
1334 utl::OStreamWrapper
* pStreamWrapper
= new utl::OStreamWrapper( aStream
);
1336 uno::Reference
< io::XOutputStream
> xOutStream( pStreamWrapper
);
1337 uno::Reference
< io::XInputStream
> xInStream( pStreamWrapper
);
1338 uno::Reference
< io::XSeekable
> xSeekable( pStreamWrapper
);
1340 if( xOutStream
.is() )
1342 this->getMetaFile( xOutStream
, bHighContrastMetaFile
);
1344 if( xInStream
.is() && xSeekable
.is() )
1347 sal_Int32 nBytesToRead
= xInStream
->available();
1348 uno::Sequence
< sal_Int8
> aSeq( nBytesToRead
);
1349 xInStream
->readBytes( aSeq
, nBytesToRead
);
1351 xInStream
->closeInput();
1357 uno::Sequence
< datatransfer::DataFlavor
> SAL_CALL
ChartView::getTransferDataFlavors()
1358 throw (uno::RuntimeException
, std::exception
)
1360 uno::Sequence
< datatransfer::DataFlavor
> aRet(2);
1362 aRet
[0] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMEType
,
1364 cppu::UnoType
<uno::Sequence
< sal_Int8
>>::get() );
1365 aRet
[1] = datatransfer::DataFlavor( lcl_aGDIMetaFileMIMETypeHighContrast
,
1367 cppu::UnoType
<uno::Sequence
< sal_Int8
>>::get() );
1371 sal_Bool SAL_CALL
ChartView::isDataFlavorSupported( const datatransfer::DataFlavor
& aFlavor
)
1372 throw (uno::RuntimeException
, std::exception
)
1374 return ( aFlavor
.MimeType
.equals(lcl_aGDIMetaFileMIMEType
) ||
1375 aFlavor
.MimeType
.equals(lcl_aGDIMetaFileMIMETypeHighContrast
) );
1378 // ____ XUnoTunnel ___
1379 ::sal_Int64 SAL_CALL
ChartView::getSomething( const uno::Sequence
< ::sal_Int8
>& aIdentifier
)
1380 throw( uno::RuntimeException
, std::exception
)
1382 if( aIdentifier
.getLength() == 16 && 0 == memcmp( ExplicitValueProvider::getUnoTunnelId().getConstArray(),
1383 aIdentifier
.getConstArray(), 16 ) )
1385 ExplicitValueProvider
* pProvider
= this;
1386 return reinterpret_cast<sal_Int64
>(pProvider
);
1391 // lang::XServiceInfo
1393 OUString SAL_CALL
ChartView::getImplementationName()
1394 throw( css::uno::RuntimeException
, std::exception
)
1396 return getImplementationName_Static();
1399 OUString
ChartView::getImplementationName_Static()
1401 return OUString(CHART_VIEW_SERVICE_IMPLEMENTATION_NAME
);
1404 sal_Bool SAL_CALL
ChartView::supportsService( const OUString
& rServiceName
)
1405 throw( css::uno::RuntimeException
, std::exception
)
1407 return cppu::supportsService(this, rServiceName
);
1410 css::uno::Sequence
< OUString
> SAL_CALL
ChartView::getSupportedServiceNames()
1411 throw( css::uno::RuntimeException
, std::exception
)
1413 return getSupportedServiceNames_Static();
1416 uno::Sequence
< OUString
> ChartView::getSupportedServiceNames_Static()
1418 uno::Sequence
< OUString
> aSNS( 1 );
1419 aSNS
.getArray()[ 0 ] = CHART_VIEW_SERVICE_NAME
;
1423 ::basegfx::B3DHomMatrix
createTransformationSceneToScreen(
1424 const ::basegfx::B2IRectangle
& rDiagramRectangleWithoutAxes
)
1426 ::basegfx::B3DHomMatrix aM
;
1427 aM
.scale(double(rDiagramRectangleWithoutAxes
.getWidth())/FIXED_SIZE_FOR_3D_CHART_VOLUME
1428 , -double(rDiagramRectangleWithoutAxes
.getHeight())/FIXED_SIZE_FOR_3D_CHART_VOLUME
, 1.0 );
1429 aM
.translate(double(rDiagramRectangleWithoutAxes
.getMinX())
1430 , double(rDiagramRectangleWithoutAxes
.getMinY()+rDiagramRectangleWithoutAxes
.getHeight()-1), 0);
1437 bool lcl_IsPieOrDonut( const uno::Reference
< XDiagram
>& xDiagram
)
1439 //special treatment for pie charts
1440 //the size is checked after complete creation to get the datalabels into the given space
1442 //todo: this is just a workaround at the moment for pie and donut labels
1443 return DiagramHelper::isPieOrDonutChart( xDiagram
);
1446 void lcl_setDefaultWritingMode( ::boost::shared_ptr
< DrawModelWrapper
> pDrawModelWrapper
, ChartModel
& rModel
)
1448 //get writing mode from parent document:
1449 if( SvtLanguageOptions().IsCTLFontEnabled() )
1453 sal_Int16 nWritingMode
=-1;
1454 uno::Reference
< beans::XPropertySet
> xParentProps( rModel
.getParent(), uno::UNO_QUERY
);
1455 uno::Reference
< style::XStyleFamiliesSupplier
> xStyleFamiliesSupplier( xParentProps
, uno::UNO_QUERY
);
1456 if( xStyleFamiliesSupplier
.is() )
1458 uno::Reference
< container::XNameAccess
> xStylesFamilies( xStyleFamiliesSupplier
->getStyleFamilies() );
1459 if( xStylesFamilies
.is() )
1461 if( !xStylesFamilies
->hasByName( "PageStyles" ) )
1463 //draw/impress is parent document
1464 uno::Reference
< lang::XMultiServiceFactory
> xFatcory( xParentProps
, uno::UNO_QUERY
);
1467 uno::Reference
< beans::XPropertySet
> xDrawDefaults( xFatcory
->createInstance( "com.sun.star.drawing.Defaults" ), uno::UNO_QUERY
);
1468 if( xDrawDefaults
.is() )
1469 xDrawDefaults
->getPropertyValue( "WritingMode" ) >>= nWritingMode
;
1474 uno::Reference
< container::XNameAccess
> xPageStyles( xStylesFamilies
->getByName( "PageStyles" ), uno::UNO_QUERY
);
1475 if( xPageStyles
.is() )
1477 OUString aPageStyle
;
1479 uno::Reference
< text::XTextDocument
> xTextDocument( xParentProps
, uno::UNO_QUERY
);
1480 if( xTextDocument
.is() )
1482 //writer is parent document
1483 //retrieve the current page style from the text cursor property PageStyleName
1485 uno::Reference
< text::XTextEmbeddedObjectsSupplier
> xTextEmbeddedObjectsSupplier( xTextDocument
, uno::UNO_QUERY
);
1486 if( xTextEmbeddedObjectsSupplier
.is() )
1488 uno::Reference
< container::XNameAccess
> xEmbeddedObjects( xTextEmbeddedObjectsSupplier
->getEmbeddedObjects() );
1489 if( xEmbeddedObjects
.is() )
1491 uno::Sequence
< OUString
> aNames( xEmbeddedObjects
->getElementNames() );
1493 sal_Int32 nCount
= aNames
.getLength();
1494 for( sal_Int32 nN
=0; nN
<nCount
; nN
++ )
1496 uno::Reference
< beans::XPropertySet
> xEmbeddedProps( xEmbeddedObjects
->getByName( aNames
[nN
] ), uno::UNO_QUERY
);
1497 if( xEmbeddedProps
.is() )
1499 static OUString aChartCLSID
= OUString( SvGlobalName( SO3_SCH_CLASSID
).GetHexName());
1501 xEmbeddedProps
->getPropertyValue( "CLSID" ) >>= aCLSID
;
1502 if( aCLSID
.equals(aChartCLSID
) )
1504 uno::Reference
< text::XTextContent
> xEmbeddedObject( xEmbeddedProps
, uno::UNO_QUERY
);
1505 if( xEmbeddedObject
.is() )
1507 uno::Reference
< text::XTextRange
> xAnchor( xEmbeddedObject
->getAnchor() );
1510 uno::Reference
< beans::XPropertySet
> xAnchorProps( xAnchor
, uno::UNO_QUERY
);
1511 if( xAnchorProps
.is() )
1513 xAnchorProps
->getPropertyValue( "WritingMode" ) >>= nWritingMode
;
1515 uno::Reference
< text::XText
> xText( xAnchor
->getText() );
1518 uno::Reference
< beans::XPropertySet
> xTextCursorProps( xText
->createTextCursor(), uno::UNO_QUERY
);
1519 if( xTextCursorProps
.is() )
1520 xTextCursorProps
->getPropertyValue( "PageStyleName" ) >>= aPageStyle
;
1530 if( aPageStyle
.isEmpty() )
1532 uno::Reference
< text::XText
> xText( xTextDocument
->getText() );
1535 uno::Reference
< beans::XPropertySet
> xTextCursorProps( xText
->createTextCursor(), uno::UNO_QUERY
);
1536 if( xTextCursorProps
.is() )
1537 xTextCursorProps
->getPropertyValue( "PageStyleName" ) >>= aPageStyle
;
1543 //Calc is parent document
1544 xParentProps
->getPropertyValue( "PageStyle" ) >>= aPageStyle
;
1545 if(aPageStyle
.isEmpty())
1546 aPageStyle
= "Default";
1548 if( nWritingMode
== -1 || nWritingMode
== text::WritingMode2::PAGE
)
1550 uno::Reference
< beans::XPropertySet
> xPageStyle( xPageStyles
->getByName( aPageStyle
), uno::UNO_QUERY
);
1551 if( xPageStyle
.is() )
1552 xPageStyle
->getPropertyValue( "WritingMode" ) >>= nWritingMode
;
1558 if( nWritingMode
!= -1 && nWritingMode
!= text::WritingMode2::PAGE
)
1560 if( pDrawModelWrapper
.get() )
1561 pDrawModelWrapper
->GetItemPool().SetPoolDefaultItem(SvxFrameDirectionItem(static_cast<SvxFrameDirection
>(nWritingMode
), EE_PARA_WRITINGDIR
) );
1564 catch( const uno::Exception
& ex
)
1566 ASSERT_EXCEPTION( ex
);
1571 sal_Int16
lcl_getDefaultWritingModeFromPool( const boost::shared_ptr
<DrawModelWrapper
>& pDrawModelWrapper
)
1573 sal_Int16 nWritingMode
= text::WritingMode2::LR_TB
;
1574 if(!pDrawModelWrapper
)
1575 return nWritingMode
;
1577 const SfxPoolItem
* pItem
= &(pDrawModelWrapper
->GetItemPool().GetDefaultItem( EE_PARA_WRITINGDIR
));
1579 nWritingMode
= static_cast< sal_Int16
>((static_cast< const SvxFrameDirectionItem
* >( pItem
))->GetValue());
1580 return nWritingMode
;
1583 } //end anonymous namespace
1585 awt::Rectangle
ChartView::impl_createDiagramAndContent( const CreateShapeParam2D
& rParam
, const awt::Size
& rPageSize
)
1587 //return the used rectangle
1588 awt::Rectangle
aUsedOuterRect(rParam
.maRemainingSpace
.X
, rParam
.maRemainingSpace
.Y
, 0, 0);
1590 uno::Reference
< XDiagram
> xDiagram( mrChartModel
.getFirstDiagram() );
1592 return aUsedOuterRect
;
1594 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
1595 if(!nDimensionCount
)
1597 //@todo handle mixed dimension
1598 nDimensionCount
= 2;
1601 basegfx::B2IRectangle aAvailableOuterRect
= BaseGFXHelper::makeRectangle(rParam
.maRemainingSpace
);
1603 const std::vector
< VCoordinateSystem
* >& rVCooSysList( rParam
.mpSeriesPlotterContainer
->getCooSysList() );
1604 SeriesPlottersType
& rSeriesPlotterList
= rParam
.mpSeriesPlotterContainer
->getSeriesPlotterList();
1606 //create VAxis, so they can give necessary information for automatic scaling
1607 uno::Reference
<chart2::XChartDocument
> const xChartDoc(&mrChartModel
);
1608 uno::Reference
<util::XNumberFormatsSupplier
> const xNumberFormatsSupplier(
1609 mrChartModel
.getNumberFormatsSupplier());
1611 for( nC
=0; nC
< rVCooSysList
.size(); nC
++)
1613 VCoordinateSystem
* pVCooSys
= rVCooSysList
[nC
];
1614 if(3==nDimensionCount
)
1616 uno::Reference
<beans::XPropertySet
> xSceneProperties( xDiagram
, uno::UNO_QUERY
);
1617 CuboidPlanePosition
eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( xSceneProperties
) );
1618 CuboidPlanePosition
eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( xSceneProperties
) );
1619 CuboidPlanePosition
eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( xSceneProperties
) );
1620 pVCooSys
->set3DWallPositions( eLeftWallPos
, eBackWallPos
, eBottomPos
);
1623 pVCooSys
->createVAxisList(xChartDoc
, rPageSize
, rParam
.maRemainingSpace
);
1626 // - prepare list of all axis and how they are used
1627 Date aNullDate
= NumberFormatterWrapper( xNumberFormatsSupplier
).getNullDate();
1628 rParam
.mpSeriesPlotterContainer
->initAxisUsageList(aNullDate
);
1629 rParam
.mpSeriesPlotterContainer
->doAutoScaling( mrChartModel
);
1630 rParam
.mpSeriesPlotterContainer
->setScalesFromCooSysToPlotter();
1631 rParam
.mpSeriesPlotterContainer
->setNumberFormatsFromAxes();
1636 drawing::Direction3D aPreferredAspectRatio
=
1637 rParam
.mpSeriesPlotterContainer
->getPreferredAspectRatio();
1639 uno::Reference
< drawing::XShapes
> xSeriesTargetInFrontOfAxis(0);
1640 uno::Reference
< drawing::XShapes
> xSeriesTargetBehindAxis(0);
1641 VDiagram
aVDiagram(xDiagram
, aPreferredAspectRatio
, nDimensionCount
);
1642 bool bIsPieOrDonut
= lcl_IsPieOrDonut(xDiagram
);
1644 aVDiagram
.init(rParam
.mxDiagramWithAxesShapes
, m_xShapeFactory
);
1645 aVDiagram
.createShapes(
1646 awt::Point(rParam
.maRemainingSpace
.X
, rParam
.maRemainingSpace
.Y
),
1647 awt::Size(rParam
.maRemainingSpace
.Width
, rParam
.maRemainingSpace
.Height
));
1649 xSeriesTargetInFrontOfAxis
= aVDiagram
.getCoordinateRegion();
1650 // It is preferrable to use full size than minimum for pie charts
1651 if (!bIsPieOrDonut
&& !rParam
.mbUseFixedInnerSize
)
1652 aVDiagram
.reduceToMimimumSize();
1655 uno::Reference
< drawing::XShapes
> xTextTargetShapes
=
1656 AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory
)->createGroup2D(rParam
.mxDiagramWithAxesShapes
);
1658 // - create axis and grids for all coordinate systems
1660 //init all coordinate systems
1661 for( nC
=0; nC
< rVCooSysList
.size(); nC
++)
1663 VCoordinateSystem
* pVCooSys
= rVCooSysList
[nC
];
1664 pVCooSys
->initPlottingTargets(xSeriesTargetInFrontOfAxis
,xTextTargetShapes
,m_xShapeFactory
,xSeriesTargetBehindAxis
);
1666 pVCooSys
->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1667 createTransformationSceneToScreen( aVDiagram
.getCurrentRectangle() ) ));
1669 pVCooSys
->initVAxisInList();
1672 //calculate resulting size respecting axis label layout and fontscaling
1674 uno::Reference
< drawing::XShape
> xBoundingShape(rParam
.mxDiagramWithAxesShapes
, uno::UNO_QUERY
);
1675 ::basegfx::B2IRectangle aConsumedOuterRect
;
1677 //use first coosys only so far; todo: calculate for more than one coosys if we have more in future
1678 //todo: this is just a workaround at the moment for pie and donut labels
1679 if( !bIsPieOrDonut
&& (!rVCooSysList
.empty()) )
1681 VCoordinateSystem
* pVCooSys
= rVCooSysList
[0];
1682 pVCooSys
->createMaximumAxesLabels();
1684 aConsumedOuterRect
= AbstractShapeFactory::getRectangleOfShape(xBoundingShape
);
1685 ::basegfx::B2IRectangle
aNewInnerRect( aVDiagram
.getCurrentRectangle() );
1686 if (!rParam
.mbUseFixedInnerSize
)
1687 aNewInnerRect
= aVDiagram
.adjustInnerSize( aConsumedOuterRect
);
1689 pVCooSys
->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1690 createTransformationSceneToScreen( aNewInnerRect
) ));
1692 //redo autoscaling to get size and text dependent automatic main increment count
1693 rParam
.mpSeriesPlotterContainer
->doAutoScaling( mrChartModel
);
1694 rParam
.mpSeriesPlotterContainer
->updateScalesAndIncrementsOnAxes();
1695 rParam
.mpSeriesPlotterContainer
->setScalesFromCooSysToPlotter();
1697 pVCooSys
->createAxesLabels();
1699 bool bLessSpaceConsumedThanExpected
= false;
1701 aConsumedOuterRect
= AbstractShapeFactory::getRectangleOfShape(xBoundingShape
);
1702 if( aConsumedOuterRect
.getMinX() > aAvailableOuterRect
.getMinX()
1703 || aConsumedOuterRect
.getMaxX() < aAvailableOuterRect
.getMaxX()
1704 || aConsumedOuterRect
.getMinY() > aAvailableOuterRect
.getMinY()
1705 || aConsumedOuterRect
.getMinY() < aAvailableOuterRect
.getMaxY() )
1706 bLessSpaceConsumedThanExpected
= true;
1709 if (bLessSpaceConsumedThanExpected
&& !rParam
.mbUseFixedInnerSize
)
1711 aVDiagram
.adjustInnerSize( aConsumedOuterRect
);
1712 pVCooSys
->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1713 createTransformationSceneToScreen( aVDiagram
.getCurrentRectangle() ) ));
1715 pVCooSys
->updatePositions();//todo: logically this belongs to the condition above, but it seems also to be necessary to give the axes group shapes the right bounding rects for hit test - probably caused by bug i106183 -> check again if fixed
1718 //create axes and grids for the final size
1719 for( nC
=0; nC
< rVCooSysList
.size(); nC
++)
1721 VCoordinateSystem
* pVCooSys
= rVCooSysList
[nC
];
1723 pVCooSys
->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1724 createTransformationSceneToScreen( aVDiagram
.getCurrentRectangle() ) ));
1726 pVCooSys
->createAxesShapes();
1727 pVCooSys
->createGridShapes();
1730 // - create data series for all charttypes
1731 m_bPointsWereSkipped
= false;
1732 SeriesPlottersType::iterator aPlotterIter
= rSeriesPlotterList
.begin();
1733 const SeriesPlottersType::iterator aPlotterEnd
= rSeriesPlotterList
.end();
1734 for( aPlotterIter
= rSeriesPlotterList
.begin(); aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
)
1736 VSeriesPlotter
* pSeriesPlotter
= &(*aPlotterIter
);
1737 OUString aCID
; //III
1738 uno::Reference
< drawing::XShapes
> xSeriesTarget(0);
1739 if( pSeriesPlotter
->WantToPlotInFrontOfAxisLine() )
1740 xSeriesTarget
= xSeriesTargetInFrontOfAxis
;
1743 xSeriesTarget
= xSeriesTargetBehindAxis
;
1744 OSL_ENSURE( !bIsPieOrDonut
, "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" );
1746 pSeriesPlotter
->initPlotter( xSeriesTarget
,xTextTargetShapes
,m_xShapeFactory
,aCID
);
1747 pSeriesPlotter
->setPageReferenceSize( rPageSize
);
1748 VCoordinateSystem
* pVCooSys
= lcl_getCooSysForPlotter( rVCooSysList
, pSeriesPlotter
);
1749 if(2==nDimensionCount
)
1750 pSeriesPlotter
->setTransformationSceneToScreen( pVCooSys
->getTransformationSceneToScreen() );
1751 //better performance for big data
1752 awt::Size
aCoordinateRegionResolution(1000,1000);
1754 //calculate resolution for coordinate system
1755 Sequence
<sal_Int32
> aCoordinateSystemResolution
= pVCooSys
->getCoordinateSystemResolution( rPageSize
, m_aPageResolution
);
1756 pSeriesPlotter
->setCoordinateSystemResolution( aCoordinateSystemResolution
);
1759 pSeriesPlotter
->createShapes();
1760 m_bPointsWereSkipped
= m_bPointsWereSkipped
|| pSeriesPlotter
->PointsWereSkipped();
1763 //recreate all with corrected sizes if requested
1766 m_bPointsWereSkipped
= false;
1768 aConsumedOuterRect
= ::basegfx::B2IRectangle( AbstractShapeFactory::getRectangleOfShape(xBoundingShape
) );
1769 ::basegfx::B2IRectangle
aNewInnerRect( aVDiagram
.getCurrentRectangle() );
1770 if (!rParam
.mbUseFixedInnerSize
)
1771 aNewInnerRect
= aVDiagram
.adjustInnerSize( aConsumedOuterRect
);
1773 for( aPlotterIter
= rSeriesPlotterList
.begin(); aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
)
1775 VSeriesPlotter
* pSeriesPlotter
= &(*aPlotterIter
);
1776 pSeriesPlotter
->releaseShapes();
1779 //clear and recreate
1780 AbstractShapeFactory::removeSubShapes( xSeriesTargetInFrontOfAxis
); //xSeriesTargetBehindAxis is a sub shape of xSeriesTargetInFrontOfAxis and will be removed here
1781 xSeriesTargetBehindAxis
.clear();
1782 AbstractShapeFactory::removeSubShapes( xTextTargetShapes
);
1784 //set new transformation
1785 for( nC
=0; nC
< rVCooSysList
.size(); nC
++)
1787 VCoordinateSystem
* pVCooSys
= rVCooSysList
[nC
];
1788 pVCooSys
->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
1789 createTransformationSceneToScreen( aNewInnerRect
) ));
1792 // - create data series for all charttypes
1793 for( aPlotterIter
= rSeriesPlotterList
.begin(); aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
)
1795 VSeriesPlotter
* pSeriesPlotter
= &(*aPlotterIter
);
1796 VCoordinateSystem
* pVCooSys
= lcl_getCooSysForPlotter( rVCooSysList
, pSeriesPlotter
);
1797 if(2==nDimensionCount
)
1798 pSeriesPlotter
->setTransformationSceneToScreen( pVCooSys
->getTransformationSceneToScreen() );
1799 pSeriesPlotter
->createShapes();
1800 m_bPointsWereSkipped
= m_bPointsWereSkipped
|| pSeriesPlotter
->PointsWereSkipped();
1803 for( aPlotterIter
= rSeriesPlotterList
.begin(); aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
)
1804 aPlotterIter
->rearrangeLabelToAvoidOverlapIfRequested(rPageSize
);
1807 if (rParam
.mbUseFixedInnerSize
)
1809 aUsedOuterRect
= awt::Rectangle( aConsumedOuterRect
.getMinX(), aConsumedOuterRect
.getMinY(), aConsumedOuterRect
.getWidth(), aConsumedOuterRect
.getHeight() );
1812 aUsedOuterRect
= rParam
.maRemainingSpace
;
1814 bool bSnapRectToUsedArea
= false;
1815 for( aPlotterIter
= rSeriesPlotterList
.begin(); aPlotterIter
!= aPlotterEnd
; ++aPlotterIter
)
1817 bSnapRectToUsedArea
= aPlotterIter
->shouldSnapRectToUsedArea();
1818 if(bSnapRectToUsedArea
)
1821 if(bSnapRectToUsedArea
)
1823 if (rParam
.mbUseFixedInnerSize
)
1824 m_aResultingDiagramRectangleExcludingAxes
= getRectangleOfObject( "PlotAreaExcludingAxes" );
1827 ::basegfx::B2IRectangle aConsumedInnerRect
= aVDiagram
.getCurrentRectangle();
1828 m_aResultingDiagramRectangleExcludingAxes
= awt::Rectangle( aConsumedInnerRect
.getMinX(), aConsumedInnerRect
.getMinY(), aConsumedInnerRect
.getWidth(), aConsumedInnerRect
.getHeight() );
1833 if (rParam
.mbUseFixedInnerSize
)
1834 m_aResultingDiagramRectangleExcludingAxes
= rParam
.maRemainingSpace
;
1837 ::basegfx::B2IRectangle aConsumedInnerRect
= aVDiagram
.getCurrentRectangle();
1838 m_aResultingDiagramRectangleExcludingAxes
= awt::Rectangle( aConsumedInnerRect
.getMinX(), aConsumedInnerRect
.getMinY(), aConsumedInnerRect
.getWidth(), aConsumedInnerRect
.getHeight() );
1842 if (rParam
.mxMarkHandles
.is())
1844 awt::Point
aPos(rParam
.maRemainingSpace
.X
, rParam
.maRemainingSpace
.Y
);
1845 awt::Size
aSize(rParam
.maRemainingSpace
.Width
, rParam
.maRemainingSpace
.Height
);
1847 bool bPosSizeExcludeAxesProperty
= true;
1848 uno::Reference
< beans::XPropertySet
> xDiaProps( xDiagram
, uno::UNO_QUERY_THROW
);
1849 if( xDiaProps
.is() )
1850 xDiaProps
->getPropertyValue("PosSizeExcludeAxes") >>= bPosSizeExcludeAxesProperty
;
1851 if (rParam
.mbUseFixedInnerSize
|| bPosSizeExcludeAxesProperty
)
1853 aPos
= awt::Point( m_aResultingDiagramRectangleExcludingAxes
.X
, m_aResultingDiagramRectangleExcludingAxes
.Y
);
1854 aSize
= awt::Size( m_aResultingDiagramRectangleExcludingAxes
.Width
, m_aResultingDiagramRectangleExcludingAxes
.Height
);
1856 rParam
.mxMarkHandles
->setPosition(aPos
);
1857 rParam
.mxMarkHandles
->setSize(aSize
);
1860 return aUsedOuterRect
;
1863 bool ChartView::getExplicitValuesForAxis(
1864 uno::Reference
< XAxis
> xAxis
1865 , ExplicitScaleData
& rExplicitScale
1866 , ExplicitIncrementData
& rExplicitIncrement
)
1873 uno::Reference
< XCoordinateSystem
> xCooSys( AxisHelper::getCoordinateSystemOfAxis(xAxis
, mrChartModel
.getFirstDiagram() ) );
1874 const VCoordinateSystem
* pVCooSys
= findInCooSysList(m_aVCooSysList
,xCooSys
);
1878 sal_Int32 nDimensionIndex
=-1;
1879 sal_Int32 nAxisIndex
=-1;
1880 if( AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
) )
1882 rExplicitScale
= pVCooSys
->getExplicitScale(nDimensionIndex
,nAxisIndex
);
1883 rExplicitIncrement
= pVCooSys
->getExplicitIncrement(nDimensionIndex
,nAxisIndex
);
1884 if( rExplicitScale
.ShiftedCategoryPosition
)
1886 //remove 'one' from max
1887 if( rExplicitScale
.AxisType
== ::com::sun::star::chart2::AxisType::DATE
)
1889 Date
aMaxDate(rExplicitScale
.NullDate
); aMaxDate
+= static_cast<long>(::rtl::math::approxFloor(rExplicitScale
.Maximum
));
1890 //for explicit scales with shifted categories we need one interval more
1891 switch( rExplicitScale
.TimeResolution
)
1893 case ::com::sun::star::chart::TimeUnit::DAY
:
1896 case ::com::sun::star::chart::TimeUnit::MONTH
:
1897 aMaxDate
= DateHelper::GetDateSomeMonthsAway(aMaxDate
,-1);
1899 case ::com::sun::star::chart::TimeUnit::YEAR
:
1900 aMaxDate
= DateHelper::GetDateSomeYearsAway(aMaxDate
,-1);
1903 rExplicitScale
.Maximum
= aMaxDate
- rExplicitScale
.NullDate
;
1905 else if( rExplicitScale
.AxisType
== ::com::sun::star::chart2::AxisType::CATEGORY
)
1906 rExplicitScale
.Maximum
-= 1.0;
1907 else if( rExplicitScale
.AxisType
== ::com::sun::star::chart2::AxisType::SERIES
)
1908 rExplicitScale
.Maximum
-= 1.0;
1915 SdrPage
* ChartView::getSdrPage()
1918 Reference
< lang::XUnoTunnel
> xUnoTunnel(m_xDrawPage
,uno::UNO_QUERY
);
1921 SvxDrawPage
* pSvxDrawPage
= reinterpret_cast<SvxDrawPage
*>(xUnoTunnel
->getSomething(
1922 SvxDrawPage::getUnoTunnelId() ));
1925 pPage
= pSvxDrawPage
->GetSdrPage();
1931 uno::Reference
< drawing::XShape
> ChartView::getShapeForCID( const OUString
& rObjectCID
)
1933 SolarMutexGuard aSolarGuard
;
1934 SdrObject
* pObj
= DrawModelWrapper::getNamedSdrObject( rObjectCID
, this->getSdrPage() );
1936 return uno::Reference
< drawing::XShape
>( pObj
->getUnoShape(), uno::UNO_QUERY
);
1940 awt::Rectangle
ChartView::getDiagramRectangleExcludingAxes()
1943 return m_aResultingDiagramRectangleExcludingAxes
;
1946 awt::Rectangle
ChartView::getRectangleOfObject( const OUString
& rObjectCID
, bool bSnapRect
)
1950 awt::Rectangle aRet
;
1951 uno::Reference
< drawing::XShape
> xShape( getShapeForCID(rObjectCID
) );
1954 //special handling for axis for old api:
1955 //same special handling for diagram
1956 ObjectType
eObjectType( ObjectIdentifier::getObjectType( rObjectCID
) );
1957 if( eObjectType
== OBJECTTYPE_AXIS
|| eObjectType
== OBJECTTYPE_DIAGRAM
)
1959 SolarMutexGuard aSolarGuard
;
1960 SvxShape
* pRoot
= SvxShape::getImplementation( xShape
);
1963 SdrObject
* pRootSdrObject
= pRoot
->GetSdrObject();
1964 if( pRootSdrObject
)
1966 SdrObjList
* pRootList
= pRootSdrObject
->GetSubList();
1969 OUString aShapeName
= "MarkHandles";
1970 if( eObjectType
== OBJECTTYPE_DIAGRAM
)
1971 aShapeName
= "PlotAreaIncludingAxes";
1972 SdrObject
* pShape
= DrawModelWrapper::getNamedSdrObject( aShapeName
, pRootList
);
1974 xShape
= uno::Reference
< drawing::XShape
>( pShape
->getUnoShape(), uno::UNO_QUERY
);
1980 awt::Size
aSize( xShape
->getSize() );
1981 awt::Point
aPoint( xShape
->getPosition() );
1982 aRet
= awt::Rectangle( aPoint
.X
, aPoint
.Y
, aSize
.Width
, aSize
.Height
);
1985 //for rotated objects the shape size and position differs from the visible rectangle
1986 SvxShape
* pShape
= SvxShape::getImplementation( xShape
);
1989 SdrObject
* pSdrObject
= pShape
->GetSdrObject();
1992 Rectangle
aSnapRect( pSdrObject
->GetSnapRect() );
1993 aRet
= awt::Rectangle(aSnapRect
.Left(),aSnapRect
.Top(),aSnapRect
.GetWidth(),aSnapRect
.GetHeight());
2001 ::boost::shared_ptr
< DrawModelWrapper
> ChartView::getDrawModelWrapper()
2003 return m_pDrawModelWrapper
;
2008 inline sal_Int32
lcl_getDiagramTitleSpace()
2010 return 200; //=0,2 cm spacing
2012 bool lcl_getPropertySwapXAndYAxis( const uno::Reference
< XDiagram
>& xDiagram
)
2014 bool bSwapXAndY
= false;
2016 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
2017 if( xCooSysContainer
.is() )
2019 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
2020 if( aCooSysList
.getLength() )
2022 uno::Reference
<beans::XPropertySet
> xProp(aCooSysList
[0], uno::UNO_QUERY
);
2025 xProp
->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXAndY
;
2027 catch( const uno::Exception
& e
)
2029 ASSERT_EXCEPTION( e
);
2038 sal_Int32
ExplicitValueProvider::getExplicitNumberFormatKeyForAxis(
2039 const Reference
< chart2::XAxis
>& xAxis
2040 , const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
2041 , const Reference
<chart2::XChartDocument
>& xChartDoc
)
2043 return AxisHelper::getExplicitNumberFormatKeyForAxis( xAxis
, xCorrespondingCoordinateSystem
, xChartDoc
2044 , true /*bSearchForParallelAxisIfNothingIsFound*/ );
2047 sal_Int32
ExplicitValueProvider::getExplicitNumberFormatKeyForDataLabel(
2048 const uno::Reference
< beans::XPropertySet
>& xSeriesOrPointProp
,
2049 const uno::Reference
< XDataSeries
>& xSeries
,
2050 sal_Int32 nPointIndex
/*-1 for whole series*/,
2051 const uno::Reference
< XDiagram
>& xDiagram
2054 sal_Int32 nFormat
=0;
2055 if( !xSeriesOrPointProp
.is() )
2058 bool bLinkToSource
= true;
2061 xSeriesOrPointProp
->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT
) >>= bLinkToSource
;
2063 catch ( const beans::UnknownPropertyException
& ) {}
2065 xSeriesOrPointProp
->getPropertyValue(CHART_UNONAME_NUMFMT
) >>= nFormat
;
2066 sal_Int32 nOldFormat
= nFormat
;
2069 uno::Reference
< chart2::XChartType
> xChartType( DataSeriesHelper::getChartTypeOfSeries( xSeries
, xDiagram
) );
2071 bool bFormatFound
= false;
2072 if( ChartTypeHelper::shouldLabelNumberFormatKeyBeDetectedFromYAxis( xChartType
) )
2074 uno::Reference
< beans::XPropertySet
> xAttachedAxisProps( DiagramHelper::getAttachedAxis( xSeries
, xDiagram
), uno::UNO_QUERY
);
2075 if (xAttachedAxisProps
.is() && (xAttachedAxisProps
->getPropertyValue(CHART_UNONAME_NUMFMT
) >>= nFormat
))
2076 bFormatFound
= true;
2080 Reference
< chart2::data::XDataSource
> xSeriesSource( xSeries
, uno::UNO_QUERY
);
2081 OUString
aRole( ChartTypeHelper::getRoleOfSequenceForDataLabelNumberFormatDetection( xChartType
) );
2083 Reference
< data::XLabeledDataSequence
> xLabeledSequence(
2084 DataSeriesHelper::getDataSequenceByRole( xSeriesSource
, aRole
, false ));
2085 if( xLabeledSequence
.is() )
2087 Reference
< data::XDataSequence
> xValues( xLabeledSequence
->getValues() );
2089 nFormat
= xValues
->getNumberFormatKeyByIndex( nPointIndex
);
2093 if (nFormat
>= 0 && nOldFormat
!= nFormat
)
2094 xSeriesOrPointProp
->setPropertyValue(CHART_UNONAME_NUMFMT
, uno::makeAny(nFormat
));
2102 sal_Int32
ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabel(
2103 const uno::Reference
< beans::XPropertySet
>& xSeriesOrPointProp
,
2104 const uno::Reference
< util::XNumberFormatsSupplier
>& xNumberFormatsSupplier
)
2106 sal_Int32 nFormat
=0;
2107 if( !xSeriesOrPointProp
.is() )
2109 if( !(xSeriesOrPointProp
->getPropertyValue("PercentageNumberFormat") >>= nFormat
) )
2111 nFormat
= DiagramHelper::getPercentNumberFormat( xNumberFormatsSupplier
);
2118 awt::Rectangle
ExplicitValueProvider::addAxisTitleSizes(
2120 , const Reference
< uno::XInterface
>& xChartView
2121 , const awt::Rectangle
& rExcludingPositionAndSize
)
2123 awt::Rectangle
aRet(rExcludingPositionAndSize
);
2125 //add axis title sizes to the diagram size
2126 uno::Reference
< chart2::XTitle
> xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION
, rModel
) );
2127 uno::Reference
< chart2::XTitle
> xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION
, rModel
) );
2128 uno::Reference
< chart2::XTitle
> xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE
, rModel
) );
2129 uno::Reference
< chart2::XTitle
> xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE
, rModel
) );
2130 if( xTitle_Height
.is() || xTitle_Width
.is() || xSecondTitle_Height
.is() || xSecondTitle_Width
.is() )
2132 ExplicitValueProvider
* pExplicitValueProvider
= ExplicitValueProvider::getExplicitValueProvider(xChartView
);
2133 if( pExplicitValueProvider
)
2135 //detect whether x axis points into x direction or not
2136 if( lcl_getPropertySwapXAndYAxis( rModel
.getFirstDiagram() ) )
2138 std::swap( xTitle_Height
, xTitle_Width
);
2139 std::swap( xSecondTitle_Height
, xSecondTitle_Width
);
2142 sal_Int32 nTitleSpaceWidth
= 0;
2143 sal_Int32 nTitleSpaceHeight
= 0;
2144 sal_Int32 nSecondTitleSpaceWidth
= 0;
2145 sal_Int32 nSecondTitleSpaceHeight
= 0;
2147 if( xTitle_Height
.is() )
2149 OUString
aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height
, rModel
) );
2150 nTitleSpaceHeight
= pExplicitValueProvider
->getRectangleOfObject( aCID_X
, true ).Height
;
2151 if( nTitleSpaceHeight
)
2152 nTitleSpaceHeight
+=lcl_getDiagramTitleSpace();
2154 if( xTitle_Width
.is() )
2156 OUString
aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width
, rModel
) );
2157 nTitleSpaceWidth
= pExplicitValueProvider
->getRectangleOfObject( aCID_Y
, true ).Width
;
2158 if(nTitleSpaceWidth
)
2159 nTitleSpaceWidth
+=lcl_getDiagramTitleSpace();
2161 if( xSecondTitle_Height
.is() )
2163 OUString
aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height
, rModel
) );
2164 nSecondTitleSpaceHeight
= pExplicitValueProvider
->getRectangleOfObject( aCID_X
, true ).Height
;
2165 if( nSecondTitleSpaceHeight
)
2166 nSecondTitleSpaceHeight
+=lcl_getDiagramTitleSpace();
2168 if( xSecondTitle_Width
.is() )
2170 OUString
aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width
, rModel
) );
2171 nSecondTitleSpaceWidth
+= pExplicitValueProvider
->getRectangleOfObject( aCID_Y
, true ).Width
;
2172 if( nSecondTitleSpaceWidth
)
2173 nSecondTitleSpaceWidth
+=lcl_getDiagramTitleSpace();
2176 aRet
.X
-= nTitleSpaceWidth
;
2177 aRet
.Y
-= nSecondTitleSpaceHeight
;
2178 aRet
.Width
+= nTitleSpaceWidth
+ nSecondTitleSpaceWidth
;
2179 aRet
.Height
+= nTitleSpaceHeight
+ nSecondTitleSpaceHeight
;
2185 awt::Rectangle
ExplicitValueProvider::substractAxisTitleSizes(
2187 , const Reference
< uno::XInterface
>& xChartView
2188 , const awt::Rectangle
& rPositionAndSizeIncludingTitles
)
2190 awt::Rectangle
aRet(rPositionAndSizeIncludingTitles
);
2192 //add axis title sizes to the diagram size
2193 uno::Reference
< chart2::XTitle
> xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION
, rModel
) );
2194 uno::Reference
< chart2::XTitle
> xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION
, rModel
) );
2195 uno::Reference
< chart2::XTitle
> xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE
, rModel
) );
2196 uno::Reference
< chart2::XTitle
> xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE
, rModel
) );
2197 if( xTitle_Height
.is() || xTitle_Width
.is() || xSecondTitle_Height
.is() || xSecondTitle_Width
.is() )
2199 ExplicitValueProvider
* pExplicitValueProvider
= ExplicitValueProvider::getExplicitValueProvider(xChartView
);
2200 if( pExplicitValueProvider
)
2202 //detect whether x axis points into x direction or not
2203 if( lcl_getPropertySwapXAndYAxis( rModel
.getFirstDiagram() ) )
2205 std::swap( xTitle_Height
, xTitle_Width
);
2206 std::swap( xSecondTitle_Height
, xSecondTitle_Width
);
2209 sal_Int32 nTitleSpaceWidth
= 0;
2210 sal_Int32 nTitleSpaceHeight
= 0;
2211 sal_Int32 nSecondTitleSpaceWidth
= 0;
2212 sal_Int32 nSecondTitleSpaceHeight
= 0;
2214 if( xTitle_Height
.is() )
2216 OUString
aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height
, rModel
) );
2217 nTitleSpaceHeight
= pExplicitValueProvider
->getRectangleOfObject( aCID_X
, true ).Height
;
2218 if( nTitleSpaceHeight
)
2219 nTitleSpaceHeight
+=lcl_getDiagramTitleSpace();
2221 if( xTitle_Width
.is() )
2223 OUString
aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width
, rModel
) );
2224 nTitleSpaceWidth
= pExplicitValueProvider
->getRectangleOfObject( aCID_Y
, true ).Width
;
2225 if(nTitleSpaceWidth
)
2226 nTitleSpaceWidth
+=lcl_getDiagramTitleSpace();
2228 if( xSecondTitle_Height
.is() )
2230 OUString
aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height
, rModel
) );
2231 nSecondTitleSpaceHeight
= pExplicitValueProvider
->getRectangleOfObject( aCID_X
, true ).Height
;
2232 if( nSecondTitleSpaceHeight
)
2233 nSecondTitleSpaceHeight
+=lcl_getDiagramTitleSpace();
2235 if( xSecondTitle_Width
.is() )
2237 OUString
aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width
, rModel
) );
2238 nSecondTitleSpaceWidth
+= pExplicitValueProvider
->getRectangleOfObject( aCID_Y
, true ).Width
;
2239 if( nSecondTitleSpaceWidth
)
2240 nSecondTitleSpaceWidth
+=lcl_getDiagramTitleSpace();
2243 aRet
.X
+= nTitleSpaceWidth
;
2244 aRet
.Y
+= nSecondTitleSpaceHeight
;
2245 aRet
.Width
-= (nTitleSpaceWidth
+ nSecondTitleSpaceWidth
);
2246 aRet
.Height
-= (nTitleSpaceHeight
+ nSecondTitleSpaceHeight
);
2254 inline double lcl_getPageLayoutDistancePercentage()
2259 bool getAvailablePosAndSizeForDiagram(
2260 CreateShapeParam2D
& rParam
, const awt::Size
& rPageSize
, const uno::Reference
<XDiagram
>& xDiagram
)
2262 rParam
.mbUseFixedInnerSize
= false;
2264 //@todo: we need a size dependent on the axis labels
2265 sal_Int32 nYDistance
= static_cast<sal_Int32
>(rPageSize
.Height
*lcl_getPageLayoutDistancePercentage());
2266 sal_Int32 nXDistance
= static_cast<sal_Int32
>(rPageSize
.Width
*lcl_getPageLayoutDistancePercentage());
2267 rParam
.maRemainingSpace
.X
+= nXDistance
;
2268 rParam
.maRemainingSpace
.Width
-= 2*nXDistance
;
2269 rParam
.maRemainingSpace
.Y
+= nYDistance
;
2270 rParam
.maRemainingSpace
.Height
-= 2*nYDistance
;
2272 if (rParam
.maRemainingSpace
.Width
<= 0 || rParam
.maRemainingSpace
.Height
<= 0)
2275 uno::Reference
< beans::XPropertySet
> xProp(xDiagram
, uno::UNO_QUERY
);
2277 bool bPosSizeExcludeAxes
= false;
2279 xProp
->getPropertyValue( "PosSizeExcludeAxes" ) >>= bPosSizeExcludeAxes
;
2282 ::com::sun::star::chart2::RelativeSize aRelativeSize
;
2283 if( xProp
.is() && (xProp
->getPropertyValue( "RelativeSize" )>>=aRelativeSize
) )
2285 rParam
.maRemainingSpace
.Height
= static_cast<sal_Int32
>(aRelativeSize
.Secondary
*rPageSize
.Height
);
2286 rParam
.maRemainingSpace
.Width
= static_cast<sal_Int32
>(aRelativeSize
.Primary
*rPageSize
.Width
);
2287 rParam
.mbUseFixedInnerSize
= bPosSizeExcludeAxes
;
2291 chart2::RelativePosition aRelativePosition
;
2292 if( xProp
.is() && (xProp
->getPropertyValue( "RelativePosition" )>>=aRelativePosition
) )
2294 //@todo decide whether x is primary or secondary
2296 //the coordinates re relative to the page
2297 double fX
= aRelativePosition
.Primary
*rPageSize
.Width
;
2298 double fY
= aRelativePosition
.Secondary
*rPageSize
.Height
;
2300 awt::Point aPos
= RelativePositionHelper::getUpperLeftCornerOfAnchoredObject(
2301 awt::Point(static_cast<sal_Int32
>(fX
),static_cast<sal_Int32
>(fY
)),
2302 awt::Size(rParam
.maRemainingSpace
.Width
, rParam
.maRemainingSpace
.Height
),
2303 aRelativePosition
.Anchor
);
2305 rParam
.maRemainingSpace
.X
= aPos
.X
;
2306 rParam
.maRemainingSpace
.Y
= aPos
.Y
;
2308 rParam
.mbUseFixedInnerSize
= bPosSizeExcludeAxes
;
2311 //ensure that the diagram does not lap out right side or out of bottom
2312 if (rParam
.maRemainingSpace
.Y
+ rParam
.maRemainingSpace
.Height
> rPageSize
.Height
)
2313 rParam
.maRemainingSpace
.Height
= rPageSize
.Height
- rParam
.maRemainingSpace
.Y
;
2315 if (rParam
.maRemainingSpace
.X
+ rParam
.maRemainingSpace
.Width
> rPageSize
.Width
)
2316 rParam
.maRemainingSpace
.Width
= rPageSize
.Width
- rParam
.maRemainingSpace
.X
;
2321 enum TitleAlignment
{ ALIGN_LEFT
, ALIGN_TOP
, ALIGN_RIGHT
, ALIGN_BOTTOM
, ALIGN_Z
};
2323 void changePositionOfAxisTitle( VTitle
* pVTitle
, TitleAlignment eAlignment
2324 , awt::Rectangle
& rDiagramPlusAxesRect
, const awt::Size
& rPageSize
)
2329 awt::Point
aNewPosition(0,0);
2330 awt::Size aTitleSize
= pVTitle
->getFinalSize();
2331 sal_Int32 nYDistance
= static_cast<sal_Int32
>(rPageSize
.Height
*lcl_getPageLayoutDistancePercentage());
2332 sal_Int32 nXDistance
= static_cast<sal_Int32
>(rPageSize
.Width
*lcl_getPageLayoutDistancePercentage());
2333 switch( eAlignment
)
2336 aNewPosition
= awt::Point( rDiagramPlusAxesRect
.X
+ rDiagramPlusAxesRect
.Width
/2
2337 , rDiagramPlusAxesRect
.Y
- aTitleSize
.Height
/2 - nYDistance
);
2340 aNewPosition
= awt::Point( rDiagramPlusAxesRect
.X
+ rDiagramPlusAxesRect
.Width
/2
2341 , rDiagramPlusAxesRect
.Y
+ rDiagramPlusAxesRect
.Height
+ aTitleSize
.Height
/2 + nYDistance
);
2344 aNewPosition
= awt::Point( rDiagramPlusAxesRect
.X
- aTitleSize
.Width
/2 - nXDistance
2345 , rDiagramPlusAxesRect
.Y
+ rDiagramPlusAxesRect
.Height
/2 );
2348 aNewPosition
= awt::Point( rDiagramPlusAxesRect
.X
+ rDiagramPlusAxesRect
.Width
+ aTitleSize
.Width
/2 + nXDistance
2349 , rDiagramPlusAxesRect
.Y
+ rDiagramPlusAxesRect
.Height
/2 );
2352 aNewPosition
= awt::Point( rDiagramPlusAxesRect
.X
+ rDiagramPlusAxesRect
.Width
+ aTitleSize
.Width
/2 + nXDistance
2353 , rDiagramPlusAxesRect
.Y
+ rDiagramPlusAxesRect
.Height
- aTitleSize
.Height
/2 );
2359 sal_Int32 nMaxY
= rPageSize
.Height
- aTitleSize
.Height
/2;
2360 sal_Int32 nMaxX
= rPageSize
.Width
- aTitleSize
.Width
/2;
2361 sal_Int32 nMinX
= aTitleSize
.Width
/2;
2362 sal_Int32 nMinY
= aTitleSize
.Height
/2;
2363 if( aNewPosition
.Y
> nMaxY
)
2364 aNewPosition
.Y
= nMaxY
;
2365 if( aNewPosition
.X
> nMaxX
)
2366 aNewPosition
.X
= nMaxX
;
2367 if( aNewPosition
.Y
< nMinY
)
2368 aNewPosition
.Y
= nMinY
;
2369 if( aNewPosition
.X
< nMinX
)
2370 aNewPosition
.X
= nMinX
;
2372 pVTitle
->changePosition( aNewPosition
);
2375 boost::shared_ptr
<VTitle
> lcl_createTitle( TitleHelper::eTitleType eType
2376 , const uno::Reference
< drawing::XShapes
>& xPageShapes
2377 , const uno::Reference
< lang::XMultiServiceFactory
>& xShapeFactory
2378 , ChartModel
& rModel
2379 , awt::Rectangle
& rRemainingSpace
2380 , const awt::Size
& rPageSize
2381 , TitleAlignment eAlignment
2382 , bool& rbAutoPosition
)
2384 boost::shared_ptr
<VTitle
> apVTitle
;
2386 // #i109336# Improve auto positioning in chart
2387 double fPercentage
= lcl_getPageLayoutDistancePercentage();
2388 sal_Int32 nXDistance
= static_cast< sal_Int32
>( rPageSize
.Width
* fPercentage
);
2389 sal_Int32 nYDistance
= static_cast< sal_Int32
>( rPageSize
.Height
* fPercentage
);
2390 if ( eType
== TitleHelper::MAIN_TITLE
)
2392 sal_Int32 nYOffset
= 135; // 1/100 mm
2393 nYDistance
+= nYOffset
;
2395 else if ( eType
== TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION
)
2397 sal_Int32 nYOffset
= 420; // 1/100 mm
2398 nYDistance
= nYOffset
;
2400 else if ( eType
== TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION
)
2402 sal_Int32 nXOffset
= 450; // 1/100 mm
2403 nXDistance
= nXOffset
;
2406 uno::Reference
< XTitle
> xTitle( TitleHelper::getTitle( eType
, rModel
) );
2407 OUString aCompleteString
= TitleHelper::getCompleteString(xTitle
);
2408 if (aCompleteString
.isEmpty())
2412 apVTitle
.reset(new VTitle(xTitle
));
2413 OUString aCID
= ObjectIdentifier::createClassifiedIdentifierForObject(xTitle
, rModel
);
2414 apVTitle
->init(xPageShapes
, xShapeFactory
, aCID
);
2415 apVTitle
->createShapes(awt::Point(0,0), rPageSize
);
2416 awt::Size aTitleUnrotatedSize
= apVTitle
->getUnrotatedSize();
2417 awt::Size aTitleSize
= apVTitle
->getFinalSize();
2420 rbAutoPosition
= true;
2421 awt::Point
aNewPosition(0,0);
2422 chart2::RelativePosition aRelativePosition
;
2423 uno::Reference
<beans::XPropertySet
> xProp(xTitle
, uno::UNO_QUERY
);
2424 if (xProp
.is() && (xProp
->getPropertyValue("RelativePosition") >>= aRelativePosition
))
2426 rbAutoPosition
= false;
2428 //@todo decide whether x is primary or secondary
2429 double fX
= aRelativePosition
.Primary
*rPageSize
.Width
;
2430 double fY
= aRelativePosition
.Secondary
*rPageSize
.Height
;
2432 double fAnglePi
= apVTitle
->getRotationAnglePi();
2433 aNewPosition
= RelativePositionHelper::getCenterOfAnchoredObject(
2434 awt::Point(static_cast<sal_Int32
>(fX
),static_cast<sal_Int32
>(fY
))
2435 , aTitleUnrotatedSize
, aRelativePosition
.Anchor
, fAnglePi
);
2437 else //auto position
2439 switch( eAlignment
)
2442 aNewPosition
= awt::Point( rRemainingSpace
.X
+ rRemainingSpace
.Width
/2
2443 , rRemainingSpace
.Y
+ aTitleSize
.Height
/2 + nYDistance
);
2446 aNewPosition
= awt::Point( rRemainingSpace
.X
+ rRemainingSpace
.Width
/2
2447 , rRemainingSpace
.Y
+ rRemainingSpace
.Height
- aTitleSize
.Height
/2 - nYDistance
);
2450 aNewPosition
= awt::Point( rRemainingSpace
.X
+ aTitleSize
.Width
/2 + nXDistance
2451 , rRemainingSpace
.Y
+ rRemainingSpace
.Height
/2 );
2454 aNewPosition
= awt::Point( rRemainingSpace
.X
+ rRemainingSpace
.Width
- aTitleSize
.Width
/2 - nXDistance
2455 , rRemainingSpace
.Y
+ rRemainingSpace
.Height
/2 );
2462 apVTitle
->changePosition( aNewPosition
);
2465 switch( eAlignment
)
2468 // Push the remaining space down from top.
2469 rRemainingSpace
.Y
+= ( aTitleSize
.Height
+ nYDistance
);
2470 rRemainingSpace
.Height
-= ( aTitleSize
.Height
+ nYDistance
);
2473 // Push the remaining space up from bottom.
2474 rRemainingSpace
.Height
-= ( aTitleSize
.Height
+ nYDistance
);
2477 // Push the remaining space to the right from left edge.
2478 rRemainingSpace
.X
+= ( aTitleSize
.Width
+ nXDistance
);
2479 rRemainingSpace
.Width
-= ( aTitleSize
.Width
+ nXDistance
);
2482 // Push the remaining space to the left from right edge.
2483 rRemainingSpace
.Width
-= ( aTitleSize
.Width
+ nXDistance
);
2492 bool lcl_createLegend( const uno::Reference
< XLegend
> & xLegend
2493 , const uno::Reference
< drawing::XShapes
>& xPageShapes
2494 , const uno::Reference
< lang::XMultiServiceFactory
>& xShapeFactory
2495 , const uno::Reference
< uno::XComponentContext
> & xContext
2496 , awt::Rectangle
& rRemainingSpace
2497 , const awt::Size
& rPageSize
2498 , ChartModel
& rModel
2499 , const std::vector
< LegendEntryProvider
* >& rLegendEntryProviderList
2500 , sal_Int16 nDefaultWritingMode
)
2502 if (!VLegend::isVisible(xLegend
))
2505 VLegend
aVLegend( xLegend
, xContext
, rLegendEntryProviderList
,
2506 xPageShapes
, xShapeFactory
, rModel
);
2507 aVLegend
.setDefaultWritingMode( nDefaultWritingMode
);
2508 aVLegend
.createShapes( awt::Size( rRemainingSpace
.Width
, rRemainingSpace
.Height
),
2510 aVLegend
.changePosition( rRemainingSpace
, rPageSize
);
2515 ChartModel
& rChartModel
2516 , const awt::Size
& rPageSize
2517 , const uno::Reference
< drawing::XShapes
>& xTarget
2518 , const uno::Reference
< lang::XMultiServiceFactory
>& xShapeFactory
2523 uno::Reference
< beans::XPropertySet
> xModelPage( rChartModel
.getPageBackground());
2524 if( ! xModelPage
.is())
2527 if( !xShapeFactory
.is() )
2531 tPropertyNameValueMap aNameValueMap
;
2532 PropertyMapper::getValueMap( aNameValueMap
, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), xModelPage
);
2534 OUString
aCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE
, OUString() ) );
2535 aNameValueMap
.insert( tPropertyNameValueMap::value_type( "Name", uno::makeAny( aCID
) ) ); //CID OUString
2537 tNameSequence aNames
;
2538 tAnySequence aValues
;
2539 PropertyMapper::getMultiPropertyListsFromValueMap( aNames
, aValues
, aNameValueMap
);
2541 AbstractShapeFactory
* pShapeFactory
= AbstractShapeFactory::getOrCreateShapeFactory(xShapeFactory
);
2542 pShapeFactory
->createRectangle(
2543 xTarget
, rPageSize
, awt::Point(0, 0), aNames
, aValues
);
2545 catch( const uno::Exception
& ex
)
2547 ASSERT_EXCEPTION( ex
);
2551 void lcl_removeEmptyGroupShapes( const Reference
< drawing::XShapes
>& xParent
)
2555 Reference
< drawing::XShapeGroup
> xParentGroup( xParent
, uno::UNO_QUERY
);
2556 if( !xParentGroup
.is() )
2558 Reference
< drawing::XDrawPage
> xPage( xParent
, uno::UNO_QUERY
);
2563 //iterate from back!
2564 for( sal_Int32 nN
= xParent
->getCount(); nN
--; )
2566 uno::Any aAny
= xParent
->getByIndex( nN
);
2567 Reference
< drawing::XShapes
> xShapes(0);
2568 if( aAny
>>= xShapes
)
2569 lcl_removeEmptyGroupShapes( xShapes
);
2570 if( xShapes
.is() && xShapes
->getCount()==0 )
2572 //remove empty group shape
2573 Reference
< drawing::XShapeGroup
> xGroup( xShapes
, uno::UNO_QUERY
);
2574 Reference
< drawing::XShape
> xShape( xShapes
, uno::UNO_QUERY
);
2576 xParent
->remove( xShape
);
2583 void ChartView::impl_refreshAddIn()
2585 if( !m_bRefreshAddIn
)
2588 uno::Reference
< beans::XPropertySet
> xProp( static_cast< ::cppu::OWeakObject
* >( &mrChartModel
), uno::UNO_QUERY
);
2591 uno::Reference
< util::XRefreshable
> xAddIn
;
2592 xProp
->getPropertyValue( "AddIn" ) >>= xAddIn
;
2595 bool bRefreshAddInAllowed
= true;
2596 xProp
->getPropertyValue( "RefreshAddInAllowed" ) >>= bRefreshAddInAllowed
;
2597 if( bRefreshAddInAllowed
)
2601 catch( const uno::Exception
& e
)
2603 ASSERT_EXCEPTION( e
);
2608 * Is it a real 3D chart with a true 3D scene or a 3D chart in a 2D scene.
2610 bool ChartView::isReal3DChart()
2612 uno::Reference
< XDiagram
> xDiagram( mrChartModel
.getFirstDiagram() );
2614 return ChartHelper::isGL3DDiagram(xDiagram
);
2617 static const char* envChartDummyFactory
= getenv("CHART_DUMMY_FACTORY");
2619 void ChartView::createShapes()
2621 osl::ResettableMutexGuard
aTimedGuard(maTimeMutex
);
2622 if(mrChartModel
.isTimeBased())
2624 maTimeBased
.bTimeBased
= true;
2627 //make sure add-in is refreshed after creating the shapes
2628 const ::comphelper::ScopeGuard
aGuard( boost::bind( &ChartView::impl_refreshAddIn
, this ) );
2630 m_aResultingDiagramRectangleExcludingAxes
= awt::Rectangle(0,0,0,0);
2631 impl_deleteCoordinateSystems();
2632 if( m_pDrawModelWrapper
)
2634 SolarMutexGuard aSolarGuard
;
2635 // #i12587# support for shapes in chart
2636 m_pDrawModelWrapper
->getSdrModel().EnableUndo( false );
2637 m_pDrawModelWrapper
->clearMainDrawPage();
2640 lcl_setDefaultWritingMode( m_pDrawModelWrapper
, mrChartModel
);
2642 awt::Size aPageSize
= mrChartModel
.getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
);
2644 AbstractShapeFactory
* pShapeFactory
= AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory
);
2645 if(!mxRootShape
.is())
2646 mxRootShape
= pShapeFactory
->getOrCreateChartRootShape( m_xDrawPage
);
2648 SdrPage
* pPage
= ChartView::getSdrPage();
2649 if(pPage
) //it is necessary to use the implementation here as the uno page does not provide a propertyset
2650 pPage
->SetSize(Size(aPageSize
.Width
,aPageSize
.Height
));
2653 OSL_FAIL("could not set page size correctly");
2655 pShapeFactory
->setPageSize(mxRootShape
, aPageSize
);
2656 pShapeFactory
->clearPage(mxRootShape
);
2658 #if HAVE_FEATURE_DESKTOP
2666 m_pGL3DPlotter
.reset();
2668 // hide OpenGL window for now in normal charts
2669 OpenGLWindow
* pWindow
= mrChartModel
.getOpenGLWindow();
2670 if(pWindow
&& !envChartDummyFactory
)
2671 pWindow
->Show(false);
2675 createShapes2D(aPageSize
);
2677 // #i12587# support for shapes in chart
2678 if ( m_pDrawModelWrapper
)
2680 SolarMutexGuard aSolarGuard
;
2681 m_pDrawModelWrapper
->getSdrModel().EnableUndo( true );
2684 if(maTimeBased
.bTimeBased
)
2686 maTimeBased
.nFrame
++;
2690 void ChartView::render()
2692 if(!isReal3DChart())
2694 AbstractShapeFactory
* pShapeFactory
= AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory
);
2695 OpenGLWindow
* pWindow
= mrChartModel
.getOpenGLWindow();
2697 pWindow
->setRenderer(mp2DRenderer
.get());
2698 bool bRender
= pShapeFactory
->preRender(mxRootShape
, pWindow
);
2701 pShapeFactory
->render(mxRootShape
, pWindow
!= mp2DRenderer
->getOpenGLWindow());
2702 pShapeFactory
->postRender(pWindow
);
2707 // util::XEventListener (base of XCloseListener)
2708 void SAL_CALL
ChartView::disposing( const lang::EventObject
& /* rSource */ )
2709 throw(uno::RuntimeException
, std::exception
)
2713 void ChartView::impl_updateView( bool bCheckLockedCtrler
)
2715 if( !m_pDrawModelWrapper
)
2718 // #i12587# support for shapes in chart
2719 if ( m_bSdrViewIsInEditMode
)
2724 if (bCheckLockedCtrler
&& mrChartModel
.hasControllersLocked())
2727 if( m_bViewDirty
&& !m_bInViewUpdate
)
2729 m_bInViewUpdate
= true;
2730 //bool bOldRefreshAddIn = m_bRefreshAddIn;
2731 //m_bRefreshAddIn = false;
2734 impl_notifyModeChangeListener("invalid");
2736 //prepare draw model
2738 SolarMutexGuard aSolarGuard
;
2739 m_pDrawModelWrapper
->lockControllers();
2744 m_bViewDirty
= false;
2745 m_bViewUpdatePending
= false;
2750 //avoid recursions due to add-in
2751 m_bRefreshAddIn
= false;
2752 m_bViewDirty
= false;
2753 m_bViewUpdatePending
= false;
2754 //delete old chart view
2756 m_bRefreshAddIn
= true;
2760 m_bViewDirty
= m_bViewUpdatePending
;
2761 m_bViewUpdatePending
= false;
2762 m_bInViewUpdate
= false;
2764 catch( const uno::Exception
& ex
)
2766 m_bViewDirty
= m_bViewUpdatePending
;
2767 m_bViewUpdatePending
= false;
2768 m_bInViewUpdate
= false;
2769 ASSERT_EXCEPTION( ex
);
2773 SolarMutexGuard aSolarGuard
;
2774 m_pDrawModelWrapper
->unlockControllers();
2777 impl_notifyModeChangeListener("valid");
2779 //m_bRefreshAddIn = bOldRefreshAddIn;
2783 // ____ XModifyListener ____
2784 void SAL_CALL
ChartView::modified( const lang::EventObject
& /* aEvent */ )
2785 throw (uno::RuntimeException
, std::exception
)
2787 m_bViewDirty
= true;
2788 if( m_bInViewUpdate
)
2789 m_bViewUpdatePending
= true;
2791 impl_notifyModeChangeListener("dirty");
2795 void ChartView::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
2797 //#i77362 change notification for changes on additional shapes are missing
2798 if( m_bInViewUpdate
)
2801 // #i12587# support for shapes in chart
2802 if ( m_bSdrViewIsInEditMode
)
2804 uno::Reference
< view::XSelectionSupplier
> xSelectionSupplier( mrChartModel
.getCurrentController(), uno::UNO_QUERY
);
2805 if ( xSelectionSupplier
.is() )
2807 OUString aSelObjCID
;
2808 uno::Any
aSelObj( xSelectionSupplier
->getSelection() );
2809 aSelObj
>>= aSelObjCID
;
2810 if ( !aSelObjCID
.isEmpty() )
2817 const SdrHint
* pSdrHint
= dynamic_cast< const SdrHint
* >(&rHint
);
2821 bool bShapeChanged
= false;
2822 switch( pSdrHint
->GetKind() )
2825 bShapeChanged
= true;
2827 case HINT_OBJINSERTED
:
2828 bShapeChanged
= true;
2830 case HINT_OBJREMOVED
:
2831 bShapeChanged
= true;
2833 case HINT_MODELCLEARED
:
2834 bShapeChanged
= true;
2837 bShapeChanged
= true;
2845 //#i76053# do not send view modified notifications for changes on the hidden page which contains e.g. the symbols for the dialogs
2846 if( ChartView::getSdrPage() != pSdrHint
->GetPage() )
2847 bShapeChanged
=false;
2853 mrChartModel
.setModified(sal_True
);
2856 void ChartView::impl_notifyModeChangeListener( const OUString
& rNewMode
)
2860 ::cppu::OInterfaceContainerHelper
* pIC
= m_aListenerContainer
2861 .getContainer( cppu::UnoType
<util::XModeChangeListener
>::get());
2864 util::ModeChangeEvent
aEvent( static_cast< uno::XWeak
* >( this ), rNewMode
);
2865 ::cppu::OInterfaceIteratorHelper
aIt( *pIC
);
2866 while( aIt
.hasMoreElements() )
2868 uno::Reference
< util::XModeChangeListener
> xListener( aIt
.next(), uno::UNO_QUERY
);
2869 if( xListener
.is() )
2870 xListener
->modeChanged( aEvent
);
2874 catch( const uno::Exception
& ex
)
2876 ASSERT_EXCEPTION( ex
);
2880 // ____ XModeChangeBroadcaster ____
2882 void SAL_CALL
ChartView::addModeChangeListener( const uno::Reference
< util::XModeChangeListener
>& xListener
)
2883 throw (uno::RuntimeException
, std::exception
)
2885 m_aListenerContainer
.addInterface(
2886 cppu::UnoType
<util::XModeChangeListener
>::get(), xListener
);
2888 void SAL_CALL
ChartView::removeModeChangeListener( const uno::Reference
< util::XModeChangeListener
>& xListener
)
2889 throw (uno::RuntimeException
, std::exception
)
2891 m_aListenerContainer
.removeInterface(
2892 cppu::UnoType
<util::XModeChangeListener
>::get(), xListener
);
2894 void SAL_CALL
ChartView::addModeChangeApproveListener( const uno::Reference
< util::XModeChangeApproveListener
>& /* _rxListener */ )
2895 throw (lang::NoSupportException
, uno::RuntimeException
, std::exception
)
2899 void SAL_CALL
ChartView::removeModeChangeApproveListener( const uno::Reference
< util::XModeChangeApproveListener
>& /* _rxListener */ )
2900 throw (lang::NoSupportException
, uno::RuntimeException
, std::exception
)
2905 // ____ XUpdatable ____
2906 void SAL_CALL
ChartView::update() throw (uno::RuntimeException
, std::exception
)
2908 impl_updateView(true);
2910 //#i100778# migrate all imported or old documents to a plot area sizing exclusive axes (in case the save settings allow for this):
2911 //Although in general it is a bad idea to change the model from within the view this is exceptionally the best place to do this special conversion.
2912 //When a view update is requested (what happens for creating the metafile or displaying
2913 //the chart in edit mode or printing) it is most likely that all necessary information are available - like the underlying spreadsheet data for example.
2914 //Those data are important for the correct axis label sizes which are needed during conversion.
2915 if( DiagramHelper::switchDiagramPositioningToExcludingPositioning( mrChartModel
, true, false ) )
2919 void SAL_CALL
ChartView::updateSoft() throw (uno::RuntimeException
, std::exception
)
2924 void SAL_CALL
ChartView::updateHard() throw (uno::RuntimeException
, std::exception
)
2926 impl_updateView(false);
2929 // ____ XPropertySet ____
2930 Reference
< beans::XPropertySetInfo
> SAL_CALL
ChartView::getPropertySetInfo()
2931 throw (uno::RuntimeException
, std::exception
)
2933 OSL_FAIL("not implemented");
2937 void SAL_CALL
ChartView::setPropertyValue( const OUString
& rPropertyName
2938 , const Any
& rValue
)
2939 throw (beans::UnknownPropertyException
, beans::PropertyVetoException
, lang::IllegalArgumentException
2940 , lang::WrappedTargetException
, uno::RuntimeException
, std::exception
)
2942 if( rPropertyName
== "Resolution" )
2944 awt::Size aNewResolution
;
2945 if( ! (rValue
>>= aNewResolution
) )
2946 throw lang::IllegalArgumentException( "Property 'Resolution' requires value of type awt::Size", 0, 0 );
2948 if( m_aPageResolution
.Width
!=aNewResolution
.Width
|| m_aPageResolution
.Height
!=aNewResolution
.Height
)
2950 //set modified only when the new resolution is higher and points were skipped before
2951 bool bSetModified
= m_bPointsWereSkipped
&& (m_aPageResolution
.Width
<aNewResolution
.Width
|| m_aPageResolution
.Height
<aNewResolution
.Height
);
2953 m_aPageResolution
= aNewResolution
;
2956 this->modified( lang::EventObject( static_cast< uno::XWeak
* >( this ) ) );
2959 else if( rPropertyName
== "ZoomFactors" )
2961 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
2962 uno::Sequence
< beans::PropertyValue
> aZoomFactors
;
2963 if( ! (rValue
>>= aZoomFactors
) )
2964 throw lang::IllegalArgumentException( "Property 'ZoomFactors' requires value of type Sequence< PropertyValue >", 0, 0 );
2966 sal_Int32 nFilterArgs
= aZoomFactors
.getLength();
2967 beans::PropertyValue
* pDataValues
= aZoomFactors
.getArray();
2968 while( nFilterArgs
-- )
2970 if ( pDataValues
->Name
== "ScaleXNumerator" )
2971 pDataValues
->Value
>>= m_nScaleXNumerator
;
2972 else if ( pDataValues
->Name
== "ScaleXDenominator" )
2973 pDataValues
->Value
>>= m_nScaleXDenominator
;
2974 else if ( pDataValues
->Name
== "ScaleYNumerator" )
2975 pDataValues
->Value
>>= m_nScaleYNumerator
;
2976 else if ( pDataValues
->Name
== "ScaleYDenominator" )
2977 pDataValues
->Value
>>= m_nScaleYDenominator
;
2982 else if( rPropertyName
== "SdrViewIsInEditMode" )
2984 //#i77362 change notification for changes on additional shapes are missing
2985 if( ! (rValue
>>= m_bSdrViewIsInEditMode
) )
2986 throw lang::IllegalArgumentException( "Property 'SdrViewIsInEditMode' requires value of type sal_Bool", 0, 0 );
2989 throw beans::UnknownPropertyException( "unknown property was tried to set to chart wizard", 0 );
2992 Any SAL_CALL
ChartView::getPropertyValue( const OUString
& rPropertyName
)
2993 throw (beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
)
2996 if( rPropertyName
== "Resolution" )
2998 aRet
= uno::makeAny( m_aPageResolution
);
3001 throw beans::UnknownPropertyException( "unknown property was tried to get from chart wizard", 0 );
3005 void SAL_CALL
ChartView::addPropertyChangeListener(
3006 const OUString
& /* aPropertyName */, const Reference
< beans::XPropertyChangeListener
>& /* xListener */ )
3007 throw (beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
)
3009 OSL_FAIL("not implemented");
3011 void SAL_CALL
ChartView::removePropertyChangeListener(
3012 const OUString
& /* aPropertyName */, const Reference
< beans::XPropertyChangeListener
>& /* aListener */ )
3013 throw (beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
)
3015 OSL_FAIL("not implemented");
3018 void SAL_CALL
ChartView::addVetoableChangeListener( const OUString
& /* PropertyName */, const Reference
< beans::XVetoableChangeListener
>& /* aListener */ )
3019 throw (beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
)
3021 OSL_FAIL("not implemented");
3024 void SAL_CALL
ChartView::removeVetoableChangeListener( const OUString
& /* PropertyName */, const Reference
< beans::XVetoableChangeListener
>& /* aListener */ )
3025 throw (beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
)
3027 OSL_FAIL("not implemented");
3030 // ____ XMultiServiceFactory ____
3032 Reference
< uno::XInterface
> ChartView::createInstance( const OUString
& aServiceSpecifier
)
3033 throw (uno::Exception
, uno::RuntimeException
, std::exception
)
3035 SolarMutexGuard aSolarGuard
;
3037 SdrModel
* pModel
= ( m_pDrawModelWrapper
? &m_pDrawModelWrapper
->getSdrModel() : NULL
);
3040 if ( aServiceSpecifier
== "com.sun.star.drawing.DashTable" )
3042 if ( !m_xDashTable
.is() )
3044 m_xDashTable
= SvxUnoDashTable_createInstance( pModel
);
3046 return m_xDashTable
;
3048 else if ( aServiceSpecifier
== "com.sun.star.drawing.GradientTable" )
3050 if ( !m_xGradientTable
.is() )
3052 m_xGradientTable
= SvxUnoGradientTable_createInstance( pModel
);
3054 return m_xGradientTable
;
3056 else if ( aServiceSpecifier
== "com.sun.star.drawing.HatchTable" )
3058 if ( !m_xHatchTable
.is() )
3060 m_xHatchTable
= SvxUnoHatchTable_createInstance( pModel
);
3062 return m_xHatchTable
;
3064 else if ( aServiceSpecifier
== "com.sun.star.drawing.BitmapTable" )
3066 if ( !m_xBitmapTable
.is() )
3068 m_xBitmapTable
= SvxUnoBitmapTable_createInstance( pModel
);
3070 return m_xBitmapTable
;
3072 else if ( aServiceSpecifier
== "com.sun.star.drawing.TransparencyGradientTable" )
3074 if ( !m_xTransGradientTable
.is() )
3076 m_xTransGradientTable
= SvxUnoTransGradientTable_createInstance( pModel
);
3078 return m_xTransGradientTable
;
3080 else if ( aServiceSpecifier
== "com.sun.star.drawing.MarkerTable" )
3082 if ( !m_xMarkerTable
.is() )
3084 m_xMarkerTable
= SvxUnoMarkerTable_createInstance( pModel
);
3086 return m_xMarkerTable
;
3093 Reference
< uno::XInterface
> ChartView::createInstanceWithArguments( const OUString
& ServiceSpecifier
, const uno::Sequence
< uno::Any
>& Arguments
)
3094 throw (uno::Exception
, uno::RuntimeException
, std::exception
)
3096 OSL_ENSURE( Arguments
.getLength(), "ChartView::createInstanceWithArguments: arguments are ignored" );
3097 (void) Arguments
; // avoid warning
3098 return createInstance( ServiceSpecifier
);
3101 uno::Sequence
< OUString
> ChartView::getAvailableServiceNames() throw (uno::RuntimeException
, std::exception
)
3103 uno::Sequence
< OUString
> aServiceNames( 6 );
3105 aServiceNames
[0] = "com.sun.star.drawing.DashTable";
3106 aServiceNames
[1] = "com.sun.star.drawing.GradientTable";
3107 aServiceNames
[2] = "com.sun.star.drawing.HatchTable";
3108 aServiceNames
[3] = "com.sun.star.drawing.BitmapTable";
3109 aServiceNames
[4] = "com.sun.star.drawing.TransparencyGradientTable";
3110 aServiceNames
[5] = "com.sun.star.drawing.MarkerTable";
3112 return aServiceNames
;
3115 OUString
ChartView::dump() throw (uno::RuntimeException
, std::exception
)
3117 #if HAVE_FEATURE_DESKTOP
3118 // Used for unit tests and in chartcontroller only, no need to drag in this when cross-compiling
3121 uno::Reference
< drawing::XShapes
> xShapes( m_xDrawPage
, uno::UNO_QUERY_THROW
);
3122 sal_Int32 n
= xShapes
->getCount();
3123 OUStringBuffer aBuffer
;
3124 for(sal_Int32 i
= 0; i
< n
; ++i
)
3126 uno::Reference
< drawing::XShapes
> xShape(xShapes
->getByIndex(i
), uno::UNO_QUERY
);
3129 XShapeDumper dumper
;
3130 OUString aString
= XShapeDumper::dump(mxRootShape
);
3131 aBuffer
.append(aString
);
3135 uno::Reference
< drawing::XShape
> xSingleShape(xShapes
->getByIndex(i
), uno::UNO_QUERY
);
3136 if(!xSingleShape
.is())
3138 XShapeDumper dumper
;
3139 OUString aString
= XShapeDumper::dump(xSingleShape
);
3140 aBuffer
.append(aString
);
3142 aBuffer
.append("\n\n");
3145 return aBuffer
.makeStringAndClear();
3151 void ChartView::setViewDirty()
3153 osl::ResettableMutexGuard
aGuard(maTimeMutex
);
3154 m_bViewDirty
= true;
3157 IMPL_LINK_NOARG_TYPED(ChartView
, UpdateTimeBased
, Timer
*, void)
3163 void ChartView::createShapes2D( const awt::Size
& rPageSize
)
3165 AbstractShapeFactory
* pShapeFactory
= AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory
);
3167 SolarMutexGuard aSolarGuard
;
3169 // todo: it would be nicer to just pass the page m_xDrawPage and format it,
3170 // but the draw page does not support XPropertySet
3171 formatPage( mrChartModel
, rPageSize
, mxRootShape
, m_xShapeFactory
);
3173 CreateShapeParam2D aParam
;
3174 aParam
.maRemainingSpace
.X
= 0;
3175 aParam
.maRemainingSpace
.Y
= 0;
3176 aParam
.maRemainingSpace
.Width
= rPageSize
.Width
;
3177 aParam
.maRemainingSpace
.Height
= rPageSize
.Height
;
3179 //create the group shape for diagram and axes first to have title and legends on top of it
3180 uno::Reference
< XDiagram
> xDiagram( mrChartModel
.getFirstDiagram() );
3181 OUString
aDiagramCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM
, OUString::number( 0 ) ) );//todo: other index if more than one diagram is possible
3182 uno::Reference
< drawing::XShapes
> xDiagramPlusAxesPlusMarkHandlesGroup_Shapes(
3183 pShapeFactory
->createGroup2D(mxRootShape
,aDiagramCID
) );
3185 aParam
.mxMarkHandles
= pShapeFactory
->createInvisibleRectangle(
3186 xDiagramPlusAxesPlusMarkHandlesGroup_Shapes
, awt::Size(0,0));
3187 AbstractShapeFactory::setShapeName(aParam
.mxMarkHandles
, "MarkHandles");
3189 aParam
.mxPlotAreaWithAxes
= pShapeFactory
->createInvisibleRectangle(
3190 xDiagramPlusAxesPlusMarkHandlesGroup_Shapes
, awt::Size(0, 0));
3191 AbstractShapeFactory::setShapeName(aParam
.mxPlotAreaWithAxes
, "PlotAreaIncludingAxes");
3193 aParam
.mxDiagramWithAxesShapes
= pShapeFactory
->createGroup2D(xDiagramPlusAxesPlusMarkHandlesGroup_Shapes
);
3195 bool bAutoPositionDummy
= true;
3198 TitleHelper::MAIN_TITLE
, mxRootShape
, m_xShapeFactory
, mrChartModel
,
3199 aParam
.maRemainingSpace
, rPageSize
, ALIGN_TOP
, bAutoPositionDummy
);
3200 if (aParam
.maRemainingSpace
.Width
<= 0 || aParam
.maRemainingSpace
.Height
<= 0)
3204 TitleHelper::SUB_TITLE
, mxRootShape
, m_xShapeFactory
, mrChartModel
,
3205 aParam
.maRemainingSpace
, rPageSize
, ALIGN_TOP
, bAutoPositionDummy
);
3206 if (aParam
.maRemainingSpace
.Width
<= 0|| aParam
.maRemainingSpace
.Height
<= 0)
3209 aParam
.mpSeriesPlotterContainer
.reset(new SeriesPlotterContainer(m_aVCooSysList
));
3210 aParam
.mpSeriesPlotterContainer
->initializeCooSysAndSeriesPlotter( mrChartModel
);
3211 if(maTimeBased
.bTimeBased
&& maTimeBased
.nFrame
!= 0)
3213 SeriesPlottersType
& rSeriesPlotter
= aParam
.mpSeriesPlotterContainer
->getSeriesPlotterList();
3214 size_t n
= rSeriesPlotter
.size();
3215 for(size_t i
= 0; i
< n
; ++i
)
3217 std::vector
<VDataSeries
*> aAllNewDataSeries
= rSeriesPlotter
[i
].getAllSeries();
3218 std::vector
< VDataSeries
* >& rAllOldDataSeries
=
3219 maTimeBased
.m_aDataSeriesList
[i
];
3220 size_t m
= std::min(aAllNewDataSeries
.size(), rAllOldDataSeries
.size());
3221 for(size_t j
= 0; j
< m
; ++j
)
3223 aAllNewDataSeries
[j
]->setOldTimeBased(
3224 rAllOldDataSeries
[j
], (maTimeBased
.nFrame
% 60)/60.0);
3230 LegendHelper::getLegend( mrChartModel
), mxRootShape
, m_xShapeFactory
, m_xCC
,
3231 aParam
.maRemainingSpace
, rPageSize
, mrChartModel
, aParam
.mpSeriesPlotterContainer
->getLegendEntryProviderList(),
3232 lcl_getDefaultWritingModeFromPool( m_pDrawModelWrapper
) );
3233 if (aParam
.maRemainingSpace
.Width
<= 0 || aParam
.maRemainingSpace
.Height
<= 0)
3236 if (!createAxisTitleShapes2D(aParam
, rPageSize
))
3239 bool bDummy
= false;
3240 bool bIsVertical
= DiagramHelper::getVertical(xDiagram
, bDummy
, bDummy
);
3242 if (getAvailablePosAndSizeForDiagram(aParam
, rPageSize
, mrChartModel
.getFirstDiagram()))
3244 awt::Rectangle aUsedOuterRect
= impl_createDiagramAndContent(aParam
, rPageSize
);
3246 if (aParam
.mxPlotAreaWithAxes
.is())
3248 aParam
.mxPlotAreaWithAxes
->setPosition(awt::Point(aUsedOuterRect
.X
, aUsedOuterRect
.Y
));
3249 aParam
.mxPlotAreaWithAxes
->setSize(awt::Size(aUsedOuterRect
.Width
, aUsedOuterRect
.Height
));
3252 //correct axis title position
3253 awt::Rectangle
aDiagramPlusAxesRect( aUsedOuterRect
);
3254 if (aParam
.mbAutoPosTitleX
)
3255 changePositionOfAxisTitle(aParam
.mpVTitleX
.get(), ALIGN_BOTTOM
, aDiagramPlusAxesRect
, rPageSize
);
3256 if (aParam
.mbAutoPosTitleY
)
3257 changePositionOfAxisTitle(aParam
.mpVTitleY
.get(), ALIGN_LEFT
, aDiagramPlusAxesRect
, rPageSize
);
3258 if (aParam
.mbAutoPosTitleZ
)
3259 changePositionOfAxisTitle(aParam
.mpVTitleZ
.get(), ALIGN_Z
, aDiagramPlusAxesRect
, rPageSize
);
3260 if (aParam
.mbAutoPosSecondTitleX
)
3261 changePositionOfAxisTitle(aParam
.mpVTitleSecondX
.get(), bIsVertical
? ALIGN_RIGHT
: ALIGN_TOP
, aDiagramPlusAxesRect
, rPageSize
);
3262 if (aParam
.mbAutoPosSecondTitleY
)
3263 changePositionOfAxisTitle(aParam
.mpVTitleSecondY
.get(), bIsVertical
? ALIGN_TOP
: ALIGN_RIGHT
, aDiagramPlusAxesRect
, rPageSize
);
3266 //cleanup: remove all empty group shapes to avoid grey border lines:
3267 lcl_removeEmptyGroupShapes( mxRootShape
);
3271 if(maTimeBased
.bTimeBased
&& maTimeBased
.nFrame
% 60 == 0)
3273 // create copy of the data for next frame
3274 SeriesPlottersType
& rSeriesPlotter
= aParam
.mpSeriesPlotterContainer
->getSeriesPlotterList();
3275 size_t n
= rSeriesPlotter
.size();
3276 maTimeBased
.m_aDataSeriesList
.clear();
3277 maTimeBased
.m_aDataSeriesList
.resize(n
);
3278 for(size_t i
= 0; i
< n
; ++i
)
3280 std::vector
<VDataSeries
*> aAllNewDataSeries
= rSeriesPlotter
[i
].getAllSeries();
3281 std::vector
<VDataSeries
*>& rAllOldDataSeries
= maTimeBased
.m_aDataSeriesList
[i
];
3282 size_t m
= aAllNewDataSeries
.size();
3283 for(size_t j
= 0; j
< m
; ++j
)
3285 rAllOldDataSeries
.push_back( aAllNewDataSeries
[j
]->
3286 createCopyForTimeBased() );
3290 if(maTimeBased
.eMode
!= MANUAL
)
3292 mrChartModel
.setTimeBased(true);
3293 mrChartModel
.getNextTimePoint();
3296 maTimeBased
.maTimer
.Stop();
3299 if(maTimeBased
.bTimeBased
&& maTimeBased
.eMode
!= MANUAL
&& !maTimeBased
.maTimer
.IsActive())
3301 maTimeBased
.maTimer
.SetTimeout(15);
3302 maTimeBased
.maTimer
.SetTimeoutHdl(LINK(this, ChartView
, UpdateTimeBased
));
3303 maTimeBased
.maTimer
.Start();
3307 bool ChartView::createAxisTitleShapes2D( CreateShapeParam2D
& rParam
, const css::awt::Size
& rPageSize
)
3309 uno::Reference
<XDiagram
> xDiagram
= mrChartModel
.getFirstDiagram();
3311 Reference
< chart2::XChartType
> xChartType( DiagramHelper::getChartTypeByIndex( xDiagram
, 0 ) );
3312 sal_Int32 nDimension
= DiagramHelper::getDimension( xDiagram
);
3314 if( ChartTypeHelper::isSupportingMainAxis( xChartType
, nDimension
, 0 ) )
3315 rParam
.mpVTitleX
= lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION
, mxRootShape
, m_xShapeFactory
, mrChartModel
3316 , rParam
.maRemainingSpace
, rPageSize
, ALIGN_BOTTOM
, rParam
.mbAutoPosTitleX
);
3317 if (rParam
.maRemainingSpace
.Width
<= 0 ||rParam
.maRemainingSpace
.Height
<= 0)
3320 if( ChartTypeHelper::isSupportingMainAxis( xChartType
, nDimension
, 1 ) )
3321 rParam
.mpVTitleY
= lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION
, mxRootShape
, m_xShapeFactory
, mrChartModel
3322 , rParam
.maRemainingSpace
, rPageSize
, ALIGN_LEFT
, rParam
.mbAutoPosTitleY
);
3323 if (rParam
.maRemainingSpace
.Width
<= 0 || rParam
.maRemainingSpace
.Height
<= 0)
3326 if( ChartTypeHelper::isSupportingMainAxis( xChartType
, nDimension
, 2 ) )
3327 rParam
.mpVTitleZ
= lcl_createTitle( TitleHelper::Z_AXIS_TITLE
, mxRootShape
, m_xShapeFactory
, mrChartModel
3328 , rParam
.maRemainingSpace
, rPageSize
, ALIGN_RIGHT
, rParam
.mbAutoPosTitleZ
);
3329 if (rParam
.maRemainingSpace
.Width
<= 0 || rParam
.maRemainingSpace
.Height
<= 0)
3332 bool bDummy
= false;
3333 bool bIsVertical
= DiagramHelper::getVertical( xDiagram
, bDummy
, bDummy
);
3335 if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType
, nDimension
, 0 ) )
3336 rParam
.mpVTitleSecondX
= lcl_createTitle( TitleHelper::SECONDARY_X_AXIS_TITLE
, mxRootShape
, m_xShapeFactory
, mrChartModel
3337 , rParam
.maRemainingSpace
, rPageSize
, bIsVertical
? ALIGN_RIGHT
: ALIGN_TOP
, rParam
.mbAutoPosSecondTitleX
);
3338 if (rParam
.maRemainingSpace
.Width
<= 0 || rParam
.maRemainingSpace
.Height
<= 0)
3341 if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType
, nDimension
, 1 ) )
3342 rParam
.mpVTitleSecondY
= lcl_createTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE
, mxRootShape
, m_xShapeFactory
, mrChartModel
3343 , rParam
.maRemainingSpace
, rPageSize
, bIsVertical
? ALIGN_TOP
: ALIGN_RIGHT
, rParam
.mbAutoPosSecondTitleY
);
3344 if (rParam
.maRemainingSpace
.Width
<= 0 || rParam
.maRemainingSpace
.Height
<= 0)
3350 void ChartView::createShapes3D()
3352 OpenGLWindow
* pWindow
= mrChartModel
.getOpenGLWindow();
3356 if( pWindow
->GetSizePixel().Width() == 0 || pWindow
->GetSizePixel().Height() == 0 )
3358 awt::Size aPageSize
= mrChartModel
.getVisualAreaSize( embed::Aspects::MSOLE_CONTENT
);
3359 Size aSize
= pWindow
->LogicToPixel( Size(aPageSize
.Width
,aPageSize
.Height
), MapUnit(MAP_100TH_MM
) );
3360 pWindow
->SetSizePixel(aSize
);
3363 uno::Reference
< XDiagram
> xDiagram( mrChartModel
.getFirstDiagram() );
3364 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
3365 if( !xCooSysContainer
.is())
3368 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
3370 if (aCooSysList
.getLength() != 1)
3371 // Supporting multiple coordinates in a truly 3D chart (which implies
3372 // it's a Cartesian coordinate system) is a bit of a challenge, if not
3376 uno::Reference
<XCoordinateSystem
> xCooSys( aCooSysList
[0] );
3378 //iterate through all chart types in the current coordinate system
3379 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
3380 OSL_ASSERT( xChartTypeContainer
.is());
3381 if( !xChartTypeContainer
.is() )
3384 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
3385 if (aChartTypeList
.getLength() != 1)
3386 // Likewise, we can't really support multiple chart types here.
3389 uno::Reference
< XChartType
> xChartType( aChartTypeList
[0] );
3391 if (!m_pGL3DPlotter
)
3393 m_pGL3DPlotter
.reset(new GL3DBarChart(xChartType
, pWindow
));
3397 GL3DBarChart
* pChart
= dynamic_cast<GL3DBarChart
*>(m_pGL3DPlotter
.get());
3399 pChart
->setOpenGLWindow(pWindow
);
3402 uno::Reference
< XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY
);
3403 OSL_ASSERT( xDataSeriesContainer
.is());
3404 if( !xDataSeriesContainer
.is() )
3407 boost::ptr_vector
<VDataSeries
> aDataSeries
;
3408 uno::Sequence
< uno::Reference
< XDataSeries
> > aSeriesList( xDataSeriesContainer
->getDataSeries() );
3409 for( sal_Int32 nS
= 0; nS
< aSeriesList
.getLength(); ++nS
)
3411 uno::Reference
< XDataSeries
> xDataSeries( aSeriesList
[nS
], uno::UNO_QUERY
);
3412 if(!xDataSeries
.is())
3415 aDataSeries
.push_back(new VDataSeries(xDataSeries
));
3418 boost::scoped_ptr
<ExplicitCategoriesProvider
> pCatProvider(new ExplicitCategoriesProvider(xCooSys
, mrChartModel
));
3420 m_pGL3DPlotter
->create3DShapes(aDataSeries
, *pCatProvider
);
3422 m_pGL3DPlotter
->render();
3425 void ChartView::updateOpenGLWindow()
3427 if(!isReal3DChart())
3428 mp2DRenderer
->updateOpenGLWindow();
3433 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
* SAL_CALL
3434 com_sun_star_comp_chart2_ChartView_get_implementation(css::uno::XComponentContext
*context
,
3435 css::uno::Sequence
<css::uno::Any
> const &)
3437 ::chart::ChartModel
*pChartModel
= new ::chart::ChartModel(context
);
3438 return cppu::acquire(new ::chart::ChartView(context
, *pChartModel
));
3441 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */