LibreOffice Module chart2 (master) 1
ChartView.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <config_feature_desktop.h>
21
23
24#include <ChartView.hxx>
26#include <Diagram.hxx>
27#include <ChartType.hxx>
28#include <DataSeries.hxx>
30#include <VDiagram.hxx>
31#include "VTitle.hxx"
32#include "VButton.hxx"
33#include <ShapeFactory.hxx>
35#include <VCoordinateSystem.hxx>
36#include <VSeriesPlotter.hxx>
37#include <CommonConverters.hxx>
38#include <TitleHelper.hxx>
39#include <Legend.hxx>
40#include <LegendHelper.hxx>
41#include "VLegend.hxx"
42#include <PropertyMapper.hxx>
43#include <ChartModel.hxx>
44#include <ChartTypeHelper.hxx>
45#include <ScaleAutomatism.hxx>
46#include <ObjectIdentifier.hxx>
47#include <DiagramHelper.hxx>
49#include <servicenames.hxx>
50#include <Axis.hxx>
51#include <AxisHelper.hxx>
52#include "AxisUsage.hxx"
53#include <AxisIndexDefines.hxx>
54#include <BaseGFXHelper.hxx>
55#include <DataSeriesHelper.hxx>
56#include <DateHelper.hxx>
58#include <defines.hxx>
59#include <dumpxmltostring.hxx>
60#include <unonames.hxx>
62#include <editeng/eeitem.hxx>
63#include <tools/globname.hxx>
69#include <rtl/math.hxx>
71#include <svx/svdpage.hxx>
72#include <svx/unopage.hxx>
73#include <utility>
74#include <vcl/svapp.hxx>
75#include <osl/mutex.hxx>
76#include <svx/unofill.hxx>
78
79#include <time.h>
80
81#include <com/sun/star/awt/Point.hpp>
82#include <com/sun/star/chart/ChartAxisPosition.hpp>
83#include <com/sun/star/chart/TimeUnit.hpp>
84#include <com/sun/star/chart2/AxisType.hpp>
85#include <com/sun/star/chart2/StackingDirection.hpp>
86#include <com/sun/star/chart2/RelativePosition.hpp>
87#include <com/sun/star/chart2/RelativeSize.hpp>
88#include <com/sun/star/chart2/data/XPivotTableDataProvider.hpp>
89#include <com/sun/star/chart2/data/PivotTableFieldEntry.hpp>
90#include <com/sun/star/drawing/GraphicExportFilter.hpp>
91#include <com/sun/star/embed/Aspects.hpp>
92#include <com/sun/star/io/XSeekable.hpp>
93#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
94#include <com/sun/star/util/XRefreshable.hpp>
95#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
96#include <com/sun/star/text/XText.hpp>
97#include <com/sun/star/text/XTextDocument.hpp>
98#include <com/sun/star/text/WritingMode2.hpp>
99#include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
100#include <com/sun/star/view/XSelectionSupplier.hpp>
101#include <svl/itempool.hxx>
102#include <svl/ctloptions.hxx>
105
106
107#include <rtl/ustring.hxx>
108
110#include <tools/stream.hxx>
111
112#include <memory>
113#include <libxml/xmlwriter.h>
114
115namespace com::sun::star::chart2 { class XChartDocument; }
116
117namespace chart {
118
119using namespace ::com::sun::star;
120using namespace ::com::sun::star::chart2;
121using ::com::sun::star::uno::Reference;
122using ::com::sun::star::uno::Sequence;
123using ::com::sun::star::uno::Any;
124
126{
127 css::awt::Rectangle maRemainingSpace;
128
129 std::shared_ptr<SeriesPlotterContainer> mpSeriesPlotterContainer;
130
131 std::shared_ptr<VTitle> mpVTitleX;
132 std::shared_ptr<VTitle> mpVTitleY;
133 std::shared_ptr<VTitle> mpVTitleZ;
134
135 std::shared_ptr<VTitle> mpVTitleSecondX;
136 std::shared_ptr<VTitle> mpVTitleSecondY;
137
140
142
146
149
151
153 mbAutoPosTitleX(true),
154 mbAutoPosTitleY(true),
155 mbAutoPosTitleZ(true),
158 mbUseFixedInnerSize(false) {}
159};
160
161
162
164 uno::Reference<uno::XComponentContext> xContext,
165 ChartModel& rModel)
166 : m_xCC(std::move(xContext))
167 , mrChartModel(rModel)
168 , m_bViewDirty(true)
169 , m_bInViewUpdate(false)
170 , m_bViewUpdatePending(false)
171 , m_bRefreshAddIn(true)
172 , m_aPageResolution(1000,1000)
173 , m_bPointsWereSkipped(false)
174 , m_nScaleXNumerator(1)
175 , m_nScaleXDenominator(1)
176 , m_nScaleYNumerator(1)
177 , m_nScaleYDenominator(1)
178 , m_bSdrViewIsInEditMode(false)
179 , m_aResultingDiagramRectangleExcludingAxes(0,0,0,0)
180{
181 init();
182}
183
185{
187 {
188 SolarMutexGuard aSolarGuard;
189 m_pDrawModelWrapper = std::make_shared< DrawModelWrapper >();
190 m_xShapeFactory = m_pDrawModelWrapper->getShapeFactory();
191 m_xDrawPage = m_pDrawModelWrapper->getMainDrawPage();
192 StartListening( m_pDrawModelWrapper->getSdrModel() );
193 }
194}
195
197{
198 init();
199}
200
202{
204 // #i120831#. In ChartView::initialize(), m_xShapeFactory is created from SdrModel::getUnoModel() and indirectly
205 // from SfxBaseModel, it needs call dispose() to make sure SfxBaseModel object is freed correctly.
207 if ( xComp.is() )
208 xComp->dispose();
209
211 {
212 SolarMutexGuard aSolarGuard;
213 EndListening( m_pDrawModelWrapper->getSdrModel() );
214 m_pDrawModelWrapper.reset();
215 }
216 m_xDrawPage = nullptr;
218}
219
221{
222 //delete all coordinate systems
223 m_aVCooSysList.clear();
224}
225
226// datatransfer::XTransferable
227namespace
228{
229constexpr OUStringLiteral lcl_aGDIMetaFileMIMEType(
230 u"application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" );
231constexpr OUStringLiteral lcl_aGDIMetaFileMIMETypeHighContrast(
232 u"application/x-openoffice-highcontrast-gdimetafile;windows_formatname=\"GDIMetaFile\"" );
233} // anonymous namespace
234
236 , bool bUseHighContrast )
237{
238 if( !m_xDrawPage.is() )
239 return;
240
241 // creating the graphic exporter
242 uno::Reference< drawing::XGraphicExportFilter > xExporter = drawing::GraphicExportFilter::create( m_xCC );
243
245 comphelper::makePropertyValue("ExportOnlyBackground", false),
246 comphelper::makePropertyValue("HighContrast", bUseHighContrast),
248 comphelper::makePropertyValue("CurrentPage", uno::Reference< uno::XInterface >( static_cast<cppu::OWeakObject*>(m_xDrawPage.get()), uno::UNO_QUERY )),
249 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
254 };
255
257 comphelper::makePropertyValue("FilterName", OUString("SVM")),
258 comphelper::makePropertyValue("OutputStream", xOutStream),
259 comphelper::makePropertyValue("FilterData", aFilterData)
260 };
261
262 xExporter->setSourceDocument( m_xDrawPage );
263 if( xExporter->filter( aProps ) )
264 {
265 xOutStream->flush();
266 xOutStream->closeOutput();
267 uno::Reference< io::XSeekable > xSeekable( xOutStream, uno::UNO_QUERY );
268 if( xSeekable.is() )
269 xSeekable->seek(0);
270 }
271}
272
273uno::Any SAL_CALL ChartView::getTransferData( const datatransfer::DataFlavor& aFlavor )
274{
275 bool bHighContrastMetaFile( aFlavor.MimeType == lcl_aGDIMetaFileMIMETypeHighContrast);
276 uno::Any aRet;
277 if( ! (bHighContrastMetaFile || aFlavor.MimeType == lcl_aGDIMetaFileMIMEType) )
278 return aRet;
279
280 update();
281
282 SvMemoryStream aStream( 1024, 1024 );
283 rtl::Reference<utl::OStreamWrapper> pStreamWrapper = new utl::OStreamWrapper( aStream );
284
285 this->getMetaFile( pStreamWrapper, bHighContrastMetaFile );
286
287 pStreamWrapper->seek(0);
288 sal_Int32 nBytesToRead = pStreamWrapper->available();
289 uno::Sequence< sal_Int8 > aSeq( nBytesToRead );
290 pStreamWrapper->readBytes( aSeq, nBytesToRead);
291 aRet <<= aSeq;
292 pStreamWrapper->closeInput();
293
294 return aRet;
295}
297{
298 return
299 {
300 { lcl_aGDIMetaFileMIMEType, "GDIMetaFile", cppu::UnoType<uno::Sequence< sal_Int8 >>::get() },
301 { lcl_aGDIMetaFileMIMETypeHighContrast, "GDIMetaFile", cppu::UnoType<uno::Sequence< sal_Int8 >>::get() }
302 };
303}
304sal_Bool SAL_CALL ChartView::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor )
305{
306 return ( aFlavor.MimeType == lcl_aGDIMetaFileMIMEType ||
307 aFlavor.MimeType == lcl_aGDIMetaFileMIMETypeHighContrast );
308}
309
310// lang::XServiceInfo
311
313{
315}
316
317sal_Bool SAL_CALL ChartView::supportsService( const OUString& rServiceName )
318{
319 return cppu::supportsService(this, rServiceName);
320}
321
322css::uno::Sequence< OUString > SAL_CALL ChartView::getSupportedServiceNames()
323{
324 return { CHART_VIEW_SERVICE_NAME };
325}
326
327static ::basegfx::B3DHomMatrix createTransformationSceneToScreen(
328 const ::basegfx::B2IRectangle& rDiagramRectangleWithoutAxes )
329{
331 aM.scale(double(rDiagramRectangleWithoutAxes.getWidth())/FIXED_SIZE_FOR_3D_CHART_VOLUME
332 , -double(rDiagramRectangleWithoutAxes.getHeight())/FIXED_SIZE_FOR_3D_CHART_VOLUME, 1.0 );
333 aM.translate(double(rDiagramRectangleWithoutAxes.getMinX())
334 , double(rDiagramRectangleWithoutAxes.getMinY()+rDiagramRectangleWithoutAxes.getHeight()-1), 0);
335 return aM;
336}
337
338namespace
339{
340
341bool lcl_IsPieOrDonut( const rtl::Reference< Diagram >& xDiagram )
342{
343 //special treatment for pie charts
344 //the size is checked after complete creation to get the datalabels into the given space
345
346 //todo: this is just a workaround at the moment for pie and donut labels
347 return xDiagram->isPieOrDonutChart();
348}
349
350void lcl_setDefaultWritingMode( const std::shared_ptr< DrawModelWrapper >& pDrawModelWrapper, ChartModel& rModel)
351{
352 //get writing mode from parent document:
354 return;
355
356 try
357 {
358 sal_Int16 nWritingMode=-1;
359 uno::Reference< beans::XPropertySet > xParentProps( rModel.getParent(), uno::UNO_QUERY );
360 uno::Reference< style::XStyleFamiliesSupplier > xStyleFamiliesSupplier( xParentProps, uno::UNO_QUERY );
361 if( xStyleFamiliesSupplier.is() )
362 {
363 uno::Reference< container::XNameAccess > xStylesFamilies( xStyleFamiliesSupplier->getStyleFamilies() );
364 if( xStylesFamilies.is() )
365 {
366 if( !xStylesFamilies->hasByName( "PageStyles" ) )
367 {
368 //draw/impress is parent document
369 uno::Reference< lang::XMultiServiceFactory > xFatcory( xParentProps, uno::UNO_QUERY );
370 if( xFatcory.is() )
371 {
372 uno::Reference< beans::XPropertySet > xDrawDefaults( xFatcory->createInstance( "com.sun.star.drawing.Defaults" ), uno::UNO_QUERY );
373 if( xDrawDefaults.is() )
374 xDrawDefaults->getPropertyValue( "WritingMode" ) >>= nWritingMode;
375 }
376 }
377 else
378 {
379 uno::Reference< container::XNameAccess > xPageStyles( xStylesFamilies->getByName( "PageStyles" ), uno::UNO_QUERY );
380 if( xPageStyles.is() )
381 {
382 OUString aPageStyle;
383
384 uno::Reference< text::XTextDocument > xTextDocument( xParentProps, uno::UNO_QUERY );
385 if( xTextDocument.is() )
386 {
387 //writer is parent document
388 //retrieve the current page style from the text cursor property PageStyleName
389
390 uno::Reference< text::XTextEmbeddedObjectsSupplier > xTextEmbeddedObjectsSupplier( xTextDocument, uno::UNO_QUERY );
391 if( xTextEmbeddedObjectsSupplier.is() )
392 {
393 uno::Reference< container::XNameAccess > xEmbeddedObjects( xTextEmbeddedObjectsSupplier->getEmbeddedObjects() );
394 if( xEmbeddedObjects.is() )
395 {
396 uno::Sequence< OUString > aNames( xEmbeddedObjects->getElementNames() );
397
398 sal_Int32 nCount = aNames.getLength();
399 for( sal_Int32 nN=0; nN<nCount; nN++ )
400 {
401 uno::Reference< beans::XPropertySet > xEmbeddedProps( xEmbeddedObjects->getByName( aNames[nN] ), uno::UNO_QUERY );
402 if( xEmbeddedProps.is() )
403 {
404 static OUString aChartCLSID = SvGlobalName( SO3_SCH_CLASSID ).GetHexName();
405 OUString aCLSID;
406 xEmbeddedProps->getPropertyValue( "CLSID" ) >>= aCLSID;
407 if( aCLSID == aChartCLSID )
408 {
409 uno::Reference< text::XTextContent > xEmbeddedObject( xEmbeddedProps, uno::UNO_QUERY );
410 if( xEmbeddedObject.is() )
411 {
412 uno::Reference< text::XTextRange > xAnchor( xEmbeddedObject->getAnchor() );
413 if( xAnchor.is() )
414 {
415 uno::Reference< beans::XPropertySet > xAnchorProps( xAnchor, uno::UNO_QUERY );
416 if( xAnchorProps.is() )
417 {
418 xAnchorProps->getPropertyValue( "WritingMode" ) >>= nWritingMode;
419 }
420 uno::Reference< text::XText > xText( xAnchor->getText() );
421 if( xText.is() )
422 {
423 uno::Reference< beans::XPropertySet > xTextCursorProps( xText->createTextCursor(), uno::UNO_QUERY );
424 if( xTextCursorProps.is() )
425 xTextCursorProps->getPropertyValue( "PageStyleName" ) >>= aPageStyle;
426 }
427 }
428 }
429 break;
430 }
431 }
432 }
433 }
434 }
435 if( aPageStyle.isEmpty() )
436 {
437 uno::Reference< text::XText > xText( xTextDocument->getText() );
438 if( xText.is() )
439 {
440 uno::Reference< beans::XPropertySet > xTextCursorProps( xText->createTextCursor(), uno::UNO_QUERY );
441 if( xTextCursorProps.is() )
442 xTextCursorProps->getPropertyValue( "PageStyleName" ) >>= aPageStyle;
443 }
444 }
445 if(aPageStyle.isEmpty())
446 aPageStyle = "Standard";
447 }
448 else
449 {
450 //Calc is parent document
451 Reference< com::sun::star::beans::XPropertySetInfo > xInfo = xParentProps->getPropertySetInfo();
452 if (xInfo->hasPropertyByName("PageStyle"))
453 {
454 xParentProps->getPropertyValue( "PageStyle" ) >>= aPageStyle;
455 }
456 if(aPageStyle.isEmpty())
457 aPageStyle = "Default";
458 }
459 if( nWritingMode == -1 || nWritingMode == text::WritingMode2::PAGE )
460 {
461 uno::Reference< beans::XPropertySet > xPageStyle( xPageStyles->getByName( aPageStyle ), uno::UNO_QUERY );
462 Reference< com::sun::star::beans::XPropertySetInfo > xInfo = xPageStyle->getPropertySetInfo();
463 if (xInfo->hasPropertyByName("WritingMode"))
464 {
465 if( xPageStyle.is() )
466 xPageStyle->getPropertyValue( "WritingMode" ) >>= nWritingMode;
467 }
468 }
469 }
470 }
471 }
472 }
473 if( nWritingMode != -1 && nWritingMode != text::WritingMode2::PAGE )
474 {
475 if( pDrawModelWrapper )
476 pDrawModelWrapper->GetItemPool().SetPoolDefaultItem(SvxFrameDirectionItem(static_cast<SvxFrameDirection>(nWritingMode), EE_PARA_WRITINGDIR) );
477 }
478 }
479 catch( const uno::Exception& )
480 {
481 DBG_UNHANDLED_EXCEPTION("chart2" );
482 }
483}
484
485sal_Int16 lcl_getDefaultWritingModeFromPool( const std::shared_ptr<DrawModelWrapper>& pDrawModelWrapper )
486{
487 sal_Int16 nWritingMode = text::WritingMode2::LR_TB;
488 if(!pDrawModelWrapper)
489 return nWritingMode;
490
491 const SfxPoolItem& rItem = pDrawModelWrapper->GetItemPool().GetDefaultItem(EE_PARA_WRITINGDIR);
492 nWritingMode
493 = static_cast<sal_Int16>(static_cast<const SvxFrameDirectionItem&>(rItem).GetValue());
494 return nWritingMode;
495}
496
497} //end anonymous namespace
498
499awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D& rParam, const awt::Size& rPageSize )
500{
501 //return the used rectangle
502 awt::Rectangle aUsedOuterRect(rParam.maRemainingSpace.X, rParam.maRemainingSpace.Y, 0, 0);
503
504 rtl::Reference< Diagram > xDiagram( mrChartModel.getFirstChartDiagram() );
505 if( !xDiagram.is())
506 return aUsedOuterRect;
507
508 sal_Int32 nDimensionCount = xDiagram->getDimension();
509 if(!nDimensionCount)
510 {
511 //@todo handle mixed dimension
512 nDimensionCount = 2;
513 }
514
516
517 const std::vector< std::unique_ptr<VCoordinateSystem> >& rVCooSysList( rParam.mpSeriesPlotterContainer->getCooSysList() );
518 auto& rSeriesPlotterList = rParam.mpSeriesPlotterContainer->getSeriesPlotterList();
519
520 //create VAxis, so they can give necessary information for automatic scaling
521 uno::Reference<util::XNumberFormatsSupplier> const xNumberFormatsSupplier(
522 mrChartModel.getNumberFormatsSupplier());
523
524 for (auto& rpVCooSys : rVCooSysList)
525 {
526 if (nDimensionCount == 3)
527 {
531 rpVCooSys->set3DWallPositions( eLeftWallPos, eBackWallPos, eBottomPos );
532 }
533 rpVCooSys->createVAxisList(&mrChartModel, rPageSize, rParam.maRemainingSpace,
534 rParam.mbUseFixedInnerSize, rSeriesPlotterList, getComponentContext());
535 }
536
537 // - prepare list of all axis and how they are used
538 Date aNullDate = NumberFormatterWrapper( xNumberFormatsSupplier ).getNullDate();
539 rParam.mpSeriesPlotterContainer->initAxisUsageList(aNullDate);
540 rParam.mpSeriesPlotterContainer->doAutoScaling( mrChartModel );
541 rParam.mpSeriesPlotterContainer->setScalesFromCooSysToPlotter();
542 rParam.mpSeriesPlotterContainer->setNumberFormatsFromAxes();
543
544 //create shapes
545
546 //aspect ratio
547 drawing::Direction3D aPreferredAspectRatio =
548 rParam.mpSeriesPlotterContainer->getPreferredAspectRatio();
549
550 rtl::Reference<SvxShapeGroupAnyD> xSeriesTargetInFrontOfAxis;
551 rtl::Reference<SvxShapeGroupAnyD> xSeriesTargetBehindAxis;
552 VDiagram aVDiagram(xDiagram, aPreferredAspectRatio, nDimensionCount);
553 {//create diagram
554 aVDiagram.init(rParam.mxDiagramWithAxesShapes);
555 aVDiagram.createShapes(
556 awt::Point(rParam.maRemainingSpace.X, rParam.maRemainingSpace.Y),
557 awt::Size(rParam.maRemainingSpace.Width, rParam.maRemainingSpace.Height));
558
559 xSeriesTargetInFrontOfAxis = aVDiagram.getCoordinateRegion();
560 // It is preferable to use full size than minimum for pie charts
561 if (!rParam.mbUseFixedInnerSize)
562 aVDiagram.reduceToMinimumSize();
563 }
564
565 rtl::Reference<SvxShapeGroup> xTextTargetShapes =
567
568 // - create axis and grids for all coordinate systems
569
570 //init all coordinate systems
571 for (auto& rpVCooSys : rVCooSysList)
572 {
573 rpVCooSys->initPlottingTargets(xSeriesTargetInFrontOfAxis, xTextTargetShapes, xSeriesTargetBehindAxis);
574
575 rpVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
577
578 rpVCooSys->initVAxisInList();
579 }
580
581 //calculate resulting size respecting axis label layout and fontscaling
582
584 ::basegfx::B2IRectangle aConsumedOuterRect;
585
586 //use first coosys only so far; todo: calculate for more than one coosys if we have more in future
587 //todo: this is just a workaround at the moment for pie and donut labels
588 bool bIsPieOrDonut = lcl_IsPieOrDonut(xDiagram);
589 if( !bIsPieOrDonut && (!rVCooSysList.empty()) )
590 {
591 VCoordinateSystem* pVCooSys = rVCooSysList[0].get();
592 pVCooSys->createMaximumAxesLabels();
593
594 aConsumedOuterRect = ShapeFactory::getRectangleOfShape(*xBoundingShape);
595 ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() );
596 if (!rParam.mbUseFixedInnerSize)
597 aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect );
598
600 createTransformationSceneToScreen( aNewInnerRect ) ));
601
602 //redo autoscaling to get size and text dependent automatic main increment count
603 rParam.mpSeriesPlotterContainer->doAutoScaling( mrChartModel );
604 rParam.mpSeriesPlotterContainer->updateScalesAndIncrementsOnAxes();
605 rParam.mpSeriesPlotterContainer->setScalesFromCooSysToPlotter();
606
607 pVCooSys->createAxesLabels();
608
609 bool bLessSpaceConsumedThanExpected = false;
610 {
611 aConsumedOuterRect = ShapeFactory::getRectangleOfShape(*xBoundingShape);
612 if( aConsumedOuterRect.getMinX() > aAvailableOuterRect.getMinX()
613 || aConsumedOuterRect.getMaxX() < aAvailableOuterRect.getMaxX()
614 || aConsumedOuterRect.getMinY() > aAvailableOuterRect.getMinY()
615 || aConsumedOuterRect.getMinY() < aAvailableOuterRect.getMaxY() )
616 {
617 bLessSpaceConsumedThanExpected = true;
618 }
619 }
620
621 if (bLessSpaceConsumedThanExpected && !rParam.mbUseFixedInnerSize)
622 {
623 aVDiagram.adjustInnerSize( aConsumedOuterRect );
626
627 // Need to re-adjust again if the labels have changed height because of
628 // text can break. Ideally this shouldn't be needed, but the chart height
629 // isn't readjusted otherwise.
630 pVCooSys->createAxesLabels();
631 aConsumedOuterRect = ShapeFactory::getRectangleOfShape(*xBoundingShape);
632 aVDiagram.adjustInnerSize(aConsumedOuterRect);
635
636 }
637 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
638 }
639
640 //create axes and grids for the final size
641 for (auto& rpVCooSys : rVCooSysList)
642 {
643 rpVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
645
646 rpVCooSys->createAxesShapes();
647 rpVCooSys->createGridShapes();
648 }
649
650 // - create data series for all charttypes
651 m_bPointsWereSkipped = false;
652 for( const std::unique_ptr<VSeriesPlotter>& aPlotter : rSeriesPlotterList )
653 {
654 VSeriesPlotter* pSeriesPlotter = aPlotter.get();
656 if( pSeriesPlotter->WantToPlotInFrontOfAxisLine() )
657 xSeriesTarget = xSeriesTargetInFrontOfAxis;
658 else
659 {
660 xSeriesTarget = xSeriesTargetBehindAxis;
661 OSL_ENSURE( !bIsPieOrDonut, "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" );
662 }
663 pSeriesPlotter->initPlotter( xSeriesTarget,xTextTargetShapes,OUString() );
664 pSeriesPlotter->setPageReferenceSize( rPageSize );
665 VCoordinateSystem* pVCooSys = SeriesPlotterContainer::getCooSysForPlotter( rVCooSysList, pSeriesPlotter );
666 if(nDimensionCount==2)
668 //better performance for big data
669 {
670 //calculate resolution for coordinate system
671 Sequence<sal_Int32> aCoordinateSystemResolution = pVCooSys->getCoordinateSystemResolution( rPageSize, m_aPageResolution );
672 pSeriesPlotter->setCoordinateSystemResolution( aCoordinateSystemResolution );
673 }
674 // Do not allow to move data labels in case of pie or donut chart, yet!
675 pSeriesPlotter->setPieLabelsAllowToMove(!bIsPieOrDonut);
676 // use the pagesize as remaining space if we have a fixed inner size
677 if( rParam.mbUseFixedInnerSize )
678 aAvailableOuterRect = BaseGFXHelper::makeRectangle(awt::Rectangle(0, 0, rPageSize.Width, rPageSize.Height));
679 // set the available space for data labels to avoid moving out from chart area
680 pSeriesPlotter->setAvailableOuterRect(aAvailableOuterRect);
681 pSeriesPlotter->createShapes();
683 }
684
685 //recreate all with corrected sizes if requested
686 if( bIsPieOrDonut )
687 {
688 m_bPointsWereSkipped = false;
689
690 aConsumedOuterRect = ShapeFactory::getRectangleOfShape(*xBoundingShape);
691 ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() );
692 if (!rParam.mbUseFixedInnerSize)
693 aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect );
694
695 for( std::unique_ptr<VSeriesPlotter>& aPlotter : rSeriesPlotterList )
696 {
697 aPlotter->releaseShapes();
698 }
699
700 //clear and recreate
701 ShapeFactory::removeSubShapes( xSeriesTargetInFrontOfAxis ); //xSeriesTargetBehindAxis is a sub shape of xSeriesTargetInFrontOfAxis and will be removed here
702 xSeriesTargetBehindAxis.clear();
703 ShapeFactory::removeSubShapes( xTextTargetShapes );
704
705 //set new transformation
706 for (auto& rpVCooSys : rVCooSysList)
707 {
708 auto aMatrix = createTransformationSceneToScreen(aNewInnerRect);
709 rpVCooSys->setTransformationSceneToScreen(B3DHomMatrixToHomogenMatrix(aMatrix));
710 }
711
712 // - create data series for all charttypes
713 for( std::unique_ptr<VSeriesPlotter>& aPlotter : rSeriesPlotterList )
714 {
715 VCoordinateSystem* pVCooSys = SeriesPlotterContainer::getCooSysForPlotter( rVCooSysList, aPlotter.get() );
716 if(nDimensionCount==2)
717 aPlotter->setTransformationSceneToScreen( pVCooSys->getTransformationSceneToScreen() );
718 // Now we can move data labels in case of pie or donut chart!
719 aPlotter->setPieLabelsAllowToMove(bIsPieOrDonut);
720 aPlotter->createShapes();
721 m_bPointsWereSkipped = m_bPointsWereSkipped || aPlotter->PointsWereSkipped();
722 }
723
724 for( std::unique_ptr<VSeriesPlotter>& aPlotter : rSeriesPlotterList )
725 aPlotter->rearrangeLabelToAvoidOverlapIfRequested(rPageSize);
726 }
727
728 if (rParam.mbUseFixedInnerSize)
729 {
730 aUsedOuterRect = awt::Rectangle( aConsumedOuterRect.getMinX(), aConsumedOuterRect.getMinY(), aConsumedOuterRect.getWidth(), aConsumedOuterRect.getHeight() );
731 }
732 else
733 aUsedOuterRect = rParam.maRemainingSpace;
734
735 bool bSnapRectToUsedArea = false;
736 for( std::unique_ptr<VSeriesPlotter>& aPlotter : rSeriesPlotterList )
737 {
738 bSnapRectToUsedArea = aPlotter->shouldSnapRectToUsedArea();
739 if(bSnapRectToUsedArea)
740 break;
741 }
742 if(bSnapRectToUsedArea)
743 {
744 if (rParam.mbUseFixedInnerSize)
746 else
747 {
748 ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle();
750 }
751 }
752 else
753 {
754 if (rParam.mbUseFixedInnerSize)
756 else
757 {
758 ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle();
760 }
761 }
762
763 if (rParam.mxMarkHandles.is())
764 {
765 awt::Point aPos(rParam.maRemainingSpace.X, rParam.maRemainingSpace.Y);
766 awt::Size aSize(rParam.maRemainingSpace.Width, rParam.maRemainingSpace.Height);
767
768 bool bPosSizeExcludeAxesProperty = true;
769 xDiagram->getPropertyValue("PosSizeExcludeAxes") >>= bPosSizeExcludeAxesProperty;
770 if (rParam.mbUseFixedInnerSize || bPosSizeExcludeAxesProperty)
771 {
774 }
775 rParam.mxMarkHandles->setPosition(aPos);
776 rParam.mxMarkHandles->setSize(aSize);
777 }
778
779 return aUsedOuterRect;
780}
781
784 , ExplicitScaleData& rExplicitScale
785 , ExplicitIncrementData& rExplicitIncrement )
786{
787 SolarMutexGuard aSolarGuard;
788
790
791 if(!xAxis.is())
792 return false;
793
796 if(!pVCooSys)
797 return false;
798
799 sal_Int32 nDimensionIndex=-1;
800 sal_Int32 nAxisIndex=-1;
801 if( !AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ) )
802 return false;
803
804 rExplicitScale = pVCooSys->getExplicitScale(nDimensionIndex,nAxisIndex);
805 rExplicitIncrement = pVCooSys->getExplicitIncrement(nDimensionIndex,nAxisIndex);
806 if( !rExplicitScale.m_bShiftedCategoryPosition )
807 return true;
808
809 //remove 'one' from max
810 if( rExplicitScale.AxisType == css::chart2::AxisType::DATE )
811 {
812 Date aMaxDate(rExplicitScale.NullDate); aMaxDate.AddDays(::rtl::math::approxFloor(rExplicitScale.Maximum));
813 //for explicit scales with shifted categories we need one interval more
814 switch( rExplicitScale.TimeResolution )
815 {
816 case css::chart::TimeUnit::DAY:
817 --aMaxDate;
818 break;
819 case css::chart::TimeUnit::MONTH:
820 aMaxDate = DateHelper::GetDateSomeMonthsAway(aMaxDate,-1);
821 break;
822 case css::chart::TimeUnit::YEAR:
823 aMaxDate = DateHelper::GetDateSomeYearsAway(aMaxDate,-1);
824 break;
825 }
826 rExplicitScale.Maximum = aMaxDate - rExplicitScale.NullDate;
827 }
828 else if( rExplicitScale.AxisType == css::chart2::AxisType::CATEGORY )
829 rExplicitScale.Maximum -= 1.0;
830 else if( rExplicitScale.AxisType == css::chart2::AxisType::SERIES )
831 rExplicitScale.Maximum -= 1.0;
832 return true;
833}
834
836{
837 if(m_xDrawPage)
838 return m_xDrawPage->GetSdrPage();
839
840 return nullptr;
841}
842
844{
845 SolarMutexGuard aSolarGuard;
846 SdrObject* pObj = DrawModelWrapper::getNamedSdrObject( rObjectCID, this->getSdrPage() );
847 if( !pObj )
848 return nullptr;
849
851 rtl::Reference<SvxShape> xShape2 = dynamic_cast<SvxShape*>(xShape.get());
852 assert(xShape2 || !xShape);
853 return xShape2;
854}
855
857{
860}
861
862awt::Rectangle ChartView::getRectangleOfObject( const OUString& rObjectCID, bool bSnapRect )
863{
865
866 awt::Rectangle aRet;
867 rtl::Reference< SvxShape > xShape = getShapeForCID(rObjectCID);
868 if(xShape.is())
869 {
870 //special handling for axis for old api:
871 //same special handling for diagram
872 ObjectType eObjectType( ObjectIdentifier::getObjectType( rObjectCID ) );
873 if( eObjectType == OBJECTTYPE_AXIS || eObjectType == OBJECTTYPE_DIAGRAM )
874 {
875 SolarMutexGuard aSolarGuard;
876 SdrObject* pRootSdrObject = xShape->GetSdrObject();
877 if( pRootSdrObject )
878 {
879 SdrObjList* pRootList = pRootSdrObject->GetSubList();
880 if( pRootList )
881 {
882 OUString aShapeName = "MarkHandles";
883 if( eObjectType == OBJECTTYPE_DIAGRAM )
884 aShapeName = "PlotAreaIncludingAxes";
885 SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( aShapeName, pRootList );
886 if( pShape )
887 {
888 xShape = dynamic_cast<SvxShape*>(pShape->getUnoShape().get());
889 assert(xShape);
890 }
891 }
892 }
893 }
894
895 awt::Size aSize( xShape->getSize() );
896 awt::Point aPoint( xShape->getPosition() );
897 aRet = awt::Rectangle( aPoint.X, aPoint.Y, aSize.Width, aSize.Height );
898 if( bSnapRect )
899 {
900 //for rotated objects the shape size and position differs from the visible rectangle
901 SdrObject* pSdrObject = xShape->GetSdrObject();
902 if( pSdrObject )
903 {
904 tools::Rectangle aSnapRect( pSdrObject->GetSnapRect() );
905 aRet = awt::Rectangle(aSnapRect.Left(),aSnapRect.Top(),aSnapRect.GetWidth(),aSnapRect.GetHeight());
906 }
907 }
908 }
909 return aRet;
910}
911
912std::shared_ptr< DrawModelWrapper > ChartView::getDrawModelWrapper()
913{
914 return m_pDrawModelWrapper;
915}
916
917namespace
918{
919
920constexpr double constPageLayoutDistancePercentage = 0.02;
921constexpr sal_Int32 constPageLayoutFixedDistance = 350;
922
923bool getAvailablePosAndSizeForDiagram(
924 CreateShapeParam2D& rParam, const awt::Size & rPageSize, rtl::Reference<Diagram> const& xDiagram)
925{
926 uno::Reference<beans::XPropertySet> const& xProp(xDiagram);
927 rParam.mbUseFixedInnerSize = false;
928
929 //@todo: we need a size dependent on the axis labels
930 rtl::Reference<ChartType> xChartType;
931 if (xDiagram)
932 xChartType = xDiagram->getChartTypeByIndex(0);
933
934 sal_Int32 nXDistance = sal_Int32(rPageSize.Width * constPageLayoutDistancePercentage);
935 sal_Int32 nYDistance = sal_Int32(rPageSize.Height * constPageLayoutDistancePercentage);
936
937 // Only pie chart uses fixed size margins
938 if (xChartType.is() && xChartType->getChartType() == CHART2_SERVICE_NAME_CHARTTYPE_PIE)
939 {
940 nXDistance = constPageLayoutFixedDistance;
941 nYDistance = constPageLayoutFixedDistance;
942 }
943
944 rParam.maRemainingSpace.X += nXDistance;
945 rParam.maRemainingSpace.Width -= 2*nXDistance;
946 rParam.maRemainingSpace.Y += nYDistance;
947 rParam.maRemainingSpace.Height -= 2*nYDistance;
948
949 bool bPosSizeExcludeAxes = false;
950 if( xProp.is() )
951 xProp->getPropertyValue( "PosSizeExcludeAxes" ) >>= bPosSizeExcludeAxes;
952
953 //size:
954 css::chart2::RelativeSize aRelativeSize;
955 if( xProp.is() && (xProp->getPropertyValue( "RelativeSize" )>>=aRelativeSize) )
956 {
957 rParam.maRemainingSpace.Height = static_cast<sal_Int32>(aRelativeSize.Secondary*rPageSize.Height);
958 rParam.maRemainingSpace.Width = static_cast<sal_Int32>(aRelativeSize.Primary*rPageSize.Width);
959 rParam.mbUseFixedInnerSize = bPosSizeExcludeAxes;
960 }
961
962 if (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0)
963 return false;
964
965 //position:
966 chart2::RelativePosition aRelativePosition;
967 if( xProp.is() && (xProp->getPropertyValue( "RelativePosition" )>>=aRelativePosition) )
968 {
969 //@todo decide whether x is primary or secondary
970
971 //the coordinates re relative to the page
972 double fX = aRelativePosition.Primary*rPageSize.Width;
973 double fY = aRelativePosition.Secondary*rPageSize.Height;
974
976 awt::Point(static_cast<sal_Int32>(fX),static_cast<sal_Int32>(fY)),
977 awt::Size(rParam.maRemainingSpace.Width, rParam.maRemainingSpace.Height),
978 aRelativePosition.Anchor);
979
980 rParam.maRemainingSpace.X = aPos.X;
981 rParam.maRemainingSpace.Y = aPos.Y;
982
983 rParam.mbUseFixedInnerSize = bPosSizeExcludeAxes;
984 }
985
986 //ensure that the diagram does not lap out right side or out of bottom
987 if (rParam.maRemainingSpace.Y + rParam.maRemainingSpace.Height > rPageSize.Height)
988 rParam.maRemainingSpace.Height = rPageSize.Height - rParam.maRemainingSpace.Y;
989
990 if (rParam.maRemainingSpace.X + rParam.maRemainingSpace.Width > rPageSize.Width)
991 rParam.maRemainingSpace.Width = rPageSize.Width - rParam.maRemainingSpace.X;
992
993 return true;
994}
995
996enum class TitleAlignment { ALIGN_LEFT, ALIGN_TOP, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_Z };
997
998void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment
999 , awt::Rectangle const & rDiagramPlusAxesRect, const awt::Size & rPageSize )
1000{
1001 if(!pVTitle)
1002 return;
1003
1004 awt::Point aNewPosition(0,0);
1005 awt::Size aTitleSize = pVTitle->getFinalSize();
1006 sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height * constPageLayoutDistancePercentage);
1007 sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width * constPageLayoutDistancePercentage);
1008 switch (eAlignment)
1009 {
1010 case TitleAlignment::ALIGN_TOP:
1011 aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2
1012 , rDiagramPlusAxesRect.Y - aTitleSize.Height/2 - nYDistance );
1013 break;
1014 case TitleAlignment::ALIGN_BOTTOM:
1015 aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width/2
1016 , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height + aTitleSize.Height/2 + nYDistance );
1017 break;
1018 case TitleAlignment::ALIGN_LEFT:
1019 aNewPosition = awt::Point( rDiagramPlusAxesRect.X - aTitleSize.Width/2 - nXDistance
1020 , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 );
1021 break;
1022 case TitleAlignment::ALIGN_RIGHT:
1023 aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance
1024 , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 );
1025 break;
1026 case TitleAlignment::ALIGN_Z:
1027 aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance
1028 , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height - aTitleSize.Height/2 );
1029 break;
1030 }
1031
1032 sal_Int32 nMaxY = rPageSize.Height - aTitleSize.Height/2;
1033 sal_Int32 nMaxX = rPageSize.Width - aTitleSize.Width/2;
1034 sal_Int32 nMinX = aTitleSize.Width/2;
1035 sal_Int32 nMinY = aTitleSize.Height/2;
1036 if( aNewPosition.Y > nMaxY )
1037 aNewPosition.Y = nMaxY;
1038 if( aNewPosition.X > nMaxX )
1039 aNewPosition.X = nMaxX;
1040 if( aNewPosition.Y < nMinY )
1041 aNewPosition.Y = nMinY;
1042 if( aNewPosition.X < nMinX )
1043 aNewPosition.X = nMinX;
1044
1045 pVTitle->changePosition( aNewPosition );
1046}
1047
1048std::shared_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType
1049 , const rtl::Reference<SvxShapeGroupAnyD>& xPageShapes
1050 , ChartModel& rModel
1051 , awt::Rectangle& rRemainingSpace
1052 , const awt::Size & rPageSize
1053 , TitleAlignment eAlignment
1054 , bool& rbAutoPosition )
1055{
1056 std::shared_ptr<VTitle> apVTitle;
1057
1058 // #i109336# Improve auto positioning in chart
1059 double fPercentage = constPageLayoutDistancePercentage;
1060 sal_Int32 nXDistance = static_cast< sal_Int32 >( rPageSize.Width * fPercentage );
1061 sal_Int32 nYDistance = static_cast< sal_Int32 >( rPageSize.Height * fPercentage );
1062 if ( eType == TitleHelper::MAIN_TITLE )
1063 {
1064 nYDistance += 135; // 1/100 mm
1065 }
1067 {
1068 nYDistance = 420; // 1/100 mm
1069 }
1071 {
1072 nXDistance = 450; // 1/100 mm
1073 }
1074
1075 rtl::Reference< Title > xTitle( TitleHelper::getTitle( eType, rModel ) );
1076 OUString aCompleteString = TitleHelper::getCompleteString(xTitle);
1077 if (aCompleteString.isEmpty() || !VTitle::isVisible(xTitle))
1078 return apVTitle;
1079
1080 //create title
1081 awt::Size aTextMaxWidth(rPageSize.Width, rPageSize.Height);
1082 bool bYAxisTitle = false;
1083 if (eType == TitleHelper::MAIN_TITLE || eType == TitleHelper::SUB_TITLE)
1084 {
1085 aTextMaxWidth.Width = static_cast<sal_Int32>(rPageSize.Width * 0.8);
1086 aTextMaxWidth.Height = static_cast<sal_Int32>(rPageSize.Height * 0.5);
1087 }
1090 {
1091 aTextMaxWidth.Width = static_cast<sal_Int32>(rPageSize.Width * 0.8);
1092 aTextMaxWidth.Height = static_cast<sal_Int32>(rPageSize.Height * 0.2);
1093 }
1096 {
1097 aTextMaxWidth.Width = static_cast<sal_Int32>(rPageSize.Width * 0.2);
1098 aTextMaxWidth.Height = static_cast<sal_Int32>(rPageSize.Height * 0.8);
1099 bYAxisTitle = true;
1100 }
1101 apVTitle = std::make_shared<VTitle>(xTitle);
1102 OUString aCID = ObjectIdentifier::createClassifiedIdentifierForObject(xTitle, &rModel);
1103 apVTitle->init(xPageShapes, aCID);
1104 apVTitle->createShapes(awt::Point(0, 0), rPageSize, aTextMaxWidth, bYAxisTitle);
1105 awt::Size aTitleUnrotatedSize = apVTitle->getUnrotatedSize();
1106 awt::Size aTitleSize = apVTitle->getFinalSize();
1107
1108 //position
1109 rbAutoPosition = true;
1110 awt::Point aNewPosition(0,0);
1111 chart2::RelativePosition aRelativePosition;
1112 if (xTitle.is() && (xTitle->getPropertyValue("RelativePosition") >>= aRelativePosition))
1113 {
1114 rbAutoPosition = false;
1115
1116 //@todo decide whether x is primary or secondary
1117 double fX = aRelativePosition.Primary*rPageSize.Width;
1118 double fY = aRelativePosition.Secondary*rPageSize.Height;
1119
1120 double fAnglePi = apVTitle->getRotationAnglePi();
1122 awt::Point(static_cast<sal_Int32>(fX),static_cast<sal_Int32>(fY))
1123 , aTitleUnrotatedSize, aRelativePosition.Anchor, fAnglePi );
1124 }
1125 else //auto position
1126 {
1127 switch( eAlignment )
1128 {
1129 case TitleAlignment::ALIGN_TOP:
1130 aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2
1131 , rRemainingSpace.Y + aTitleSize.Height/2 + nYDistance );
1132 break;
1133 case TitleAlignment::ALIGN_BOTTOM:
1134 aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width/2
1135 , rRemainingSpace.Y + rRemainingSpace.Height - aTitleSize.Height/2 - nYDistance );
1136 break;
1137 case TitleAlignment::ALIGN_LEFT:
1138 aNewPosition = awt::Point( rRemainingSpace.X + aTitleSize.Width/2 + nXDistance
1139 , rRemainingSpace.Y + rRemainingSpace.Height/2 );
1140 break;
1141 case TitleAlignment::ALIGN_RIGHT:
1142 aNewPosition = awt::Point( rRemainingSpace.X + rRemainingSpace.Width - aTitleSize.Width/2 - nXDistance
1143 , rRemainingSpace.Y + rRemainingSpace.Height/2 );
1144 break;
1145 case TitleAlignment::ALIGN_Z:
1146 break;
1147
1148 }
1149 }
1150 apVTitle->changePosition( aNewPosition );
1151
1152 //remaining space
1153 switch( eAlignment )
1154 {
1155 case TitleAlignment::ALIGN_TOP:
1156 // Push the remaining space down from top.
1157 rRemainingSpace.Y += ( aTitleSize.Height + nYDistance );
1158 rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance );
1159 break;
1160 case TitleAlignment::ALIGN_BOTTOM:
1161 // Push the remaining space up from bottom.
1162 rRemainingSpace.Height -= ( aTitleSize.Height + nYDistance );
1163 break;
1164 case TitleAlignment::ALIGN_LEFT:
1165 // Push the remaining space to the right from left edge.
1166 rRemainingSpace.X += ( aTitleSize.Width + nXDistance );
1167 rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance );
1168 break;
1169 case TitleAlignment::ALIGN_RIGHT:
1170 // Push the remaining space to the left from right edge.
1171 rRemainingSpace.Width -= ( aTitleSize.Width + nXDistance );
1172 break;
1173 case TitleAlignment::ALIGN_Z:
1174 break;
1175 }
1176
1177 return apVTitle;
1178}
1179
1180bool lcl_createLegend( const rtl::Reference< Legend > & xLegend
1181 , const rtl::Reference<SvxShapeGroupAnyD>& xPageShapes
1182 , const uno::Reference< uno::XComponentContext > & xContext
1183 , awt::Rectangle & rRemainingSpace
1184 , const awt::Size & rPageSize
1185 , ChartModel& rModel
1186 , std::vector< LegendEntryProvider* >&& rLegendEntryProviderList
1187 , sal_Int16 nDefaultWritingMode )
1188{
1189 if (!VLegend::isVisible(xLegend))
1190 return false;
1191
1192 awt::Size rDefaultLegendSize;
1193 VLegend aVLegend( xLegend, xContext, std::move(rLegendEntryProviderList),
1194 xPageShapes, rModel);
1195 aVLegend.setDefaultWritingMode( nDefaultWritingMode );
1196 aVLegend.createShapes( awt::Size( rRemainingSpace.Width, rRemainingSpace.Height ),
1197 rPageSize, rDefaultLegendSize );
1198 aVLegend.changePosition( rRemainingSpace, rPageSize, rDefaultLegendSize );
1199 return true;
1200}
1201
1202void lcl_createButtons(const rtl::Reference<SvxShapeGroupAnyD>& xPageShapes,
1203 ChartModel& rModel,
1204 awt::Rectangle& rRemainingSpace)
1205{
1206 uno::Reference<chart2::data::XPivotTableDataProvider> xPivotTableDataProvider(rModel.getDataProvider(), uno::UNO_QUERY);
1207 if (!xPivotTableDataProvider.is())
1208 return;
1209
1210 uno::Reference<beans::XPropertySet> xModelPage(rModel.getPageBackground());
1211
1212 awt::Size aSize(4000, 700); // size of the button
1213
1214 tools::Long x = 0;
1215
1216 if (xPivotTableDataProvider->getPageFields().hasElements())
1217 {
1218 x = 0;
1219
1220 const css::uno::Sequence<chart2::data::PivotTableFieldEntry> aPivotFieldEntries = xPivotTableDataProvider->getPageFields();
1221 for (css::chart2::data::PivotTableFieldEntry const & rPageFieldEntry : aPivotFieldEntries)
1222 {
1223 VButton aButton;
1224 aButton.init(xPageShapes);
1225 awt::Point aNewPosition(rRemainingSpace.X + x + 100, rRemainingSpace.Y + 100);
1226 sal_Int32 nDimensionIndex = rPageFieldEntry.DimensionIndex;
1227 OUString aFieldOutputDescription = xPivotTableDataProvider->getFieldOutputDescription(nDimensionIndex);
1228 aButton.setLabel(rPageFieldEntry.Name + " | " + aFieldOutputDescription);
1229 aButton.setCID("FieldButton.Page." + OUString::number(nDimensionIndex));
1230 aButton.setPosition(aNewPosition);
1231 aButton.setSize(aSize);
1232 if (rPageFieldEntry.HasHiddenMembers)
1233 aButton.setArrowColor(Color(0x0000FF));
1234
1235 aButton.createShapes(xModelPage);
1236 x += aSize.Width + 100;
1237 }
1238 rRemainingSpace.Y += (aSize.Height + 100 + 100);
1239 rRemainingSpace.Height -= (aSize.Height + 100 + 100);
1240 }
1241
1242 aSize = awt::Size(3000, 700); // size of the button
1243
1244 if (!xPivotTableDataProvider->getRowFields().hasElements())
1245 return;
1246
1247 x = 200;
1248 const css::uno::Sequence<chart2::data::PivotTableFieldEntry> aPivotFieldEntries = xPivotTableDataProvider->getRowFields();
1249 for (css::chart2::data::PivotTableFieldEntry const & rRowFieldEntry : aPivotFieldEntries)
1250 {
1251 VButton aButton;
1252 aButton.init(xPageShapes);
1253 awt::Point aNewPosition(rRemainingSpace.X + x + 100,
1254 rRemainingSpace.Y + rRemainingSpace.Height - aSize.Height - 100);
1255 aButton.setLabel(rRowFieldEntry.Name);
1256 aButton.setCID("FieldButton.Row." + OUString::number(rRowFieldEntry.DimensionIndex));
1257 aButton.setPosition(aNewPosition);
1258 aButton.setSize(aSize);
1259 if ( rRowFieldEntry.Name == "Data" )
1260 {
1261 aButton.setBGColor( Color(0x00F6F6F6) );
1262 aButton.showArrow( false );
1263 }
1264 else if (rRowFieldEntry.HasHiddenMembers)
1265 aButton.setArrowColor(Color(0x0000FF));
1266 aButton.createShapes(xModelPage);
1267 x += aSize.Width + 100;
1268 }
1269 rRemainingSpace.Height -= (aSize.Height + 100 + 100);
1270}
1271
1272void formatPage(
1273 ChartModel& rChartModel
1274 , const awt::Size& rPageSize
1275 , const rtl::Reference<SvxShapeGroupAnyD>& xTarget
1276 )
1277{
1278 try
1279 {
1280 uno::Reference< beans::XPropertySet > xModelPage( rChartModel.getPageBackground());
1281 if( ! xModelPage.is())
1282 return;
1283
1284 //format page
1285 tPropertyNameValueMap aNameValueMap;
1287
1289 aNameValueMap.emplace( "Name", uno::Any( aCID ) ); //CID OUString
1290
1291 tNameSequence aNames;
1292 tAnySequence aValues;
1293 PropertyMapper::getMultiPropertyListsFromValueMap( aNames, aValues, aNameValueMap );
1294
1296 xTarget, rPageSize, awt::Point(0, 0), aNames, aValues);
1297 }
1298 catch( const uno::Exception & )
1299 {
1300 DBG_UNHANDLED_EXCEPTION("chart2" );
1301 }
1302}
1303
1304void lcl_removeEmptyGroupShapes( const SdrObject& rParent )
1305{
1306 SdrObjList* pObjList = rParent.getChildrenOfSdrObject();
1307 if (!pObjList || pObjList->GetObjCount() == 0)
1308 return;
1309
1310 //iterate from back!
1311 for(auto nIdx = static_cast<sal_Int32>(pObjList->GetObjCount() - 1); nIdx >= 0; --nIdx)
1312 {
1313 SdrObject* pChildSdrObject = pObjList->GetObj(nIdx);
1314 SdrObjList* pChildObjList = pChildSdrObject->getChildrenOfSdrObject();
1315 if (!pChildObjList)
1316 continue;
1317 if (pChildObjList->GetObjCount() == 0)
1318 {
1319 //remove empty group shape
1320 pObjList->NbcRemoveObject(nIdx);
1321 }
1322 else
1323 lcl_removeEmptyGroupShapes(*pChildSdrObject);
1324 }
1325}
1326
1327}
1328
1330{
1331 if( !m_bRefreshAddIn )
1332 return;
1333
1334 uno::Reference< beans::XPropertySet > xProp( static_cast< ::cppu::OWeakObject* >( &mrChartModel ), uno::UNO_QUERY );
1335 if( !xProp.is())
1336 return;
1337
1338 try
1339 {
1341 xProp->getPropertyValue( "AddIn" ) >>= xAddIn;
1342 if( xAddIn.is() )
1343 {
1344 bool bRefreshAddInAllowed = true;
1345 xProp->getPropertyValue( "RefreshAddInAllowed" ) >>= bRefreshAddInAllowed;
1346 if( bRefreshAddInAllowed )
1347 xAddIn->refresh();
1348 }
1349 }
1350 catch( const uno::Exception& )
1351 {
1352 TOOLS_WARN_EXCEPTION("chart2", "" );
1353 }
1354}
1355
1357{
1358 SolarMutexGuard aSolarGuard;
1359
1360 std::unique_lock aTimedGuard(maTimeMutex);
1361 if(mrChartModel.isTimeBased())
1362 {
1363 maTimeBased.bTimeBased = true;
1364 }
1365
1366 //make sure add-in is refreshed after creating the shapes
1367 const ::comphelper::ScopeGuard aGuard( [this]() { this->impl_refreshAddIn(); } );
1368
1369 m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle(0,0,0,0);
1372 {
1373 // #i12587# support for shapes in chart
1374 m_pDrawModelWrapper->getSdrModel().EnableUndo( false );
1375 m_pDrawModelWrapper->clearMainDrawPage();
1376 }
1377
1378 lcl_setDefaultWritingMode( m_pDrawModelWrapper, mrChartModel );
1379
1380 awt::Size aPageSize = mrChartModel.getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1381
1382 if(!mxRootShape.is())
1384
1385 SdrPage* pPage = getSdrPage();
1386
1387 if (pPage) //it is necessary to use the implementation here as the uno page does not provide a propertyset
1388 {
1389 pPage->SetSize(Size(aPageSize.Width,aPageSize.Height));
1390 }
1391 else
1392 {
1393 OSL_FAIL("could not set page size correctly");
1394 }
1396
1397 createShapes2D(aPageSize);
1398
1399 // #i12587# support for shapes in chart
1400 if ( m_pDrawModelWrapper )
1401 {
1402 m_pDrawModelWrapper->getSdrModel().EnableUndo( true );
1403 }
1404
1406 {
1408 }
1409}
1410
1411// util::XEventListener (base of XCloseListener)
1412void SAL_CALL ChartView::disposing( const lang::EventObject& /* rSource */ )
1413{
1414}
1415
1416void ChartView::impl_updateView( bool bCheckLockedCtrler )
1417{
1418 if( !m_pDrawModelWrapper )
1419 return;
1420
1421 // #i12587# support for shapes in chart
1423 {
1424 return;
1425 }
1426
1427 if (bCheckLockedCtrler && mrChartModel.hasControllersLocked())
1428 return;
1429
1431 return;
1432
1433 m_bInViewUpdate = true;
1434 //bool bOldRefreshAddIn = m_bRefreshAddIn;
1435 //m_bRefreshAddIn = false;
1436 try
1437 {
1439
1440 //prepare draw model
1441 {
1442 SolarMutexGuard aSolarGuard;
1443 m_pDrawModelWrapper->lockControllers();
1444 }
1445
1446 //create chart view
1447 {
1448 m_bViewDirty = false;
1449 m_bViewUpdatePending = false;
1450 createShapes();
1451
1452 if( m_bViewDirty )
1453 {
1454 //avoid recursions due to add-in
1455 m_bRefreshAddIn = false;
1456 m_bViewDirty = false;
1457 m_bViewUpdatePending = false;
1458 //delete old chart view
1459 createShapes();
1460 m_bRefreshAddIn = true;
1461 }
1462 }
1463
1465 m_bViewUpdatePending = false;
1466 m_bInViewUpdate = false;
1467 }
1468 catch( const uno::Exception& )
1469 {
1470 DBG_UNHANDLED_EXCEPTION("chart2" );
1472 m_bViewUpdatePending = false;
1473 m_bInViewUpdate = false;
1474 }
1475
1476 {
1477 SolarMutexGuard aSolarGuard;
1478 m_pDrawModelWrapper->unlockControllers();
1479 }
1480
1482
1483 //m_bRefreshAddIn = bOldRefreshAddIn;
1484}
1485
1486// ____ XModifyListener ____
1487void SAL_CALL ChartView::modified( const lang::EventObject& /* aEvent */ )
1488{
1489 m_bViewDirty = true;
1490 if( m_bInViewUpdate )
1491 m_bViewUpdatePending = true;
1492
1494}
1495
1496//SfxListener
1497void ChartView::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1498{
1499 //#i77362 change notification for changes on additional shapes are missing
1500 if( m_bInViewUpdate )
1501 return;
1502
1503 // #i12587# support for shapes in chart
1505 {
1506 uno::Reference< view::XSelectionSupplier > xSelectionSupplier( mrChartModel.getCurrentController(), uno::UNO_QUERY );
1507 if ( xSelectionSupplier.is() )
1508 {
1509 OUString aSelObjCID;
1510 uno::Any aSelObj( xSelectionSupplier->getSelection() );
1511 aSelObj >>= aSelObjCID;
1512 if ( !aSelObjCID.isEmpty() )
1513 {
1514 return;
1515 }
1516 }
1517 }
1518
1519 if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
1520 return;
1521 const SdrHint* pSdrHint = static_cast< const SdrHint* >(&rHint);
1522
1523 bool bShapeChanged = false;
1524 switch( pSdrHint->GetKind() )
1525 {
1526 case SdrHintKind::ObjectChange:
1527 bShapeChanged = true;
1528 break;
1529 case SdrHintKind::ObjectInserted:
1530 bShapeChanged = true;
1531 break;
1532 case SdrHintKind::ObjectRemoved:
1533 bShapeChanged = true;
1534 break;
1535 case SdrHintKind::ModelCleared:
1536 bShapeChanged = true;
1537 break;
1538 case SdrHintKind::EndEdit:
1539 bShapeChanged = true;
1540 break;
1541 default:
1542 break;
1543 }
1544
1545 if(bShapeChanged)
1546 {
1547 //#i76053# do not send view modified notifications for changes on the hidden page which contains e.g. the symbols for the dialogs
1548 if( ChartView::getSdrPage() != pSdrHint->GetPage() )
1549 bShapeChanged=false;
1550 }
1551
1552 if(!bShapeChanged)
1553 return;
1554
1555 mrChartModel.setModified(true);
1556}
1557
1558void ChartView::impl_notifyModeChangeListener( const OUString& rNewMode )
1559{
1560 try
1561 {
1562 std::unique_lock g(m_aMutex);
1564 {
1565 util::ModeChangeEvent aEvent( static_cast< uno::XWeak* >( this ), rNewMode );
1566 m_aModeChangeListeners.notifyEach( g, &css::util::XModeChangeListener::modeChanged, aEvent);
1567 }
1568 }
1569 catch( const uno::Exception& )
1570 {
1571 DBG_UNHANDLED_EXCEPTION("chart2");
1572 }
1573}
1574
1575// ____ XModeChangeBroadcaster ____
1576
1578{
1579 std::unique_lock g(m_aMutex);
1580 m_aModeChangeListeners.addInterface(g, xListener );
1581}
1583{
1584 std::unique_lock g(m_aMutex);
1586}
1588{
1589
1590}
1592{
1593
1594}
1595
1596// ____ XUpdatable ____
1597void SAL_CALL ChartView::update()
1598{
1600
1601 //#i100778# migrate all imported or old documents to a plot area sizing exclusive axes (in case the save settings allow for this):
1602 //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.
1603 //When a view update is requested (what happens for creating the metafile or displaying
1604 //the chart in edit mode or printing) it is most likely that all necessary information is available - like the underlying spreadsheet data for example.
1605 //Those data are important for the correct axis label sizes which are needed during conversion.
1608}
1609
1611{
1612 update();
1613}
1614
1616{
1617 impl_updateView(false);
1618}
1619
1620// ____ XPropertySet ____
1622{
1623 OSL_FAIL("not implemented");
1624 return nullptr;
1625}
1626
1627void SAL_CALL ChartView::setPropertyValue( const OUString& rPropertyName
1628 , const Any& rValue )
1629{
1630 if( rPropertyName == "Resolution" )
1631 {
1632 awt::Size aNewResolution;
1633 if( ! (rValue >>= aNewResolution) )
1634 throw lang::IllegalArgumentException( "Property 'Resolution' requires value of type awt::Size", nullptr, 0 );
1635
1636 if( m_aPageResolution.Width!=aNewResolution.Width || m_aPageResolution.Height!=aNewResolution.Height )
1637 {
1638 //set modified only when the new resolution is higher and points were skipped before
1639 bool bSetModified = m_bPointsWereSkipped && (m_aPageResolution.Width<aNewResolution.Width || m_aPageResolution.Height<aNewResolution.Height);
1640
1641 m_aPageResolution = aNewResolution;
1642
1643 if( bSetModified )
1644 this->modified( lang::EventObject( static_cast< uno::XWeak* >( this ) ) );
1645 }
1646 }
1647 else if( rPropertyName == "ZoomFactors" )
1648 {
1649 //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100%
1651 if( ! (rValue >>= aZoomFactors) )
1652 throw lang::IllegalArgumentException( "Property 'ZoomFactors' requires value of type Sequence< PropertyValue >", nullptr, 0 );
1653
1654 sal_Int32 nFilterArgs = aZoomFactors.getLength();
1655 const beans::PropertyValue* pDataValues = aZoomFactors.getConstArray();
1656 while( nFilterArgs-- )
1657 {
1658 if ( pDataValues->Name == "ScaleXNumerator" )
1659 pDataValues->Value >>= m_nScaleXNumerator;
1660 else if ( pDataValues->Name == "ScaleXDenominator" )
1661 pDataValues->Value >>= m_nScaleXDenominator;
1662 else if ( pDataValues->Name == "ScaleYNumerator" )
1663 pDataValues->Value >>= m_nScaleYNumerator;
1664 else if ( pDataValues->Name == "ScaleYDenominator" )
1665 pDataValues->Value >>= m_nScaleYDenominator;
1666
1667 pDataValues++;
1668 }
1669 }
1670 else if( rPropertyName == "SdrViewIsInEditMode" )
1671 {
1672 //#i77362 change notification for changes on additional shapes are missing
1673 if( ! (rValue >>= m_bSdrViewIsInEditMode) )
1674 throw lang::IllegalArgumentException( "Property 'SdrViewIsInEditMode' requires value of type sal_Bool", nullptr, 0 );
1675 }
1676 else
1677 throw beans::UnknownPropertyException( "unknown property was tried to set to chart wizard " + rPropertyName, nullptr );
1678}
1679
1680Any SAL_CALL ChartView::getPropertyValue( const OUString& rPropertyName )
1681{
1682 if( rPropertyName != "Resolution" )
1683 throw beans::UnknownPropertyException( "unknown property was tried to get from chart wizard " + rPropertyName, nullptr );
1684
1685 return Any(m_aPageResolution);
1686}
1687
1689 const OUString& /* aPropertyName */, const Reference< beans::XPropertyChangeListener >& /* xListener */ )
1690{
1691 OSL_FAIL("not implemented");
1692}
1694 const OUString& /* aPropertyName */, const Reference< beans::XPropertyChangeListener >& /* aListener */ )
1695{
1696 OSL_FAIL("not implemented");
1697}
1698
1699void SAL_CALL ChartView::addVetoableChangeListener( const OUString& /* PropertyName */, const Reference< beans::XVetoableChangeListener >& /* aListener */ )
1700{
1701 OSL_FAIL("not implemented");
1702}
1703
1704void SAL_CALL ChartView::removeVetoableChangeListener( const OUString& /* PropertyName */, const Reference< beans::XVetoableChangeListener >& /* aListener */ )
1705{
1706 OSL_FAIL("not implemented");
1707}
1708
1709// ____ XMultiServiceFactory ____
1710
1712{
1713 SolarMutexGuard aSolarGuard;
1714
1715 SdrModel* pModel = ( m_pDrawModelWrapper ? &m_pDrawModelWrapper->getSdrModel() : nullptr );
1716 if ( pModel )
1717 {
1718 if ( aServiceSpecifier == "com.sun.star.drawing.DashTable" )
1719 {
1720 if ( !m_xDashTable.is() )
1721 {
1723 }
1724 return m_xDashTable;
1725 }
1726 else if ( aServiceSpecifier == "com.sun.star.drawing.GradientTable" )
1727 {
1728 if ( !m_xGradientTable.is() )
1729 {
1731 }
1732 return m_xGradientTable;
1733 }
1734 else if ( aServiceSpecifier == "com.sun.star.drawing.HatchTable" )
1735 {
1736 if ( !m_xHatchTable.is() )
1737 {
1739 }
1740 return m_xHatchTable;
1741 }
1742 else if ( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" )
1743 {
1744 if ( !m_xBitmapTable.is() )
1745 {
1747 }
1748 return m_xBitmapTable;
1749 }
1750 else if ( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" )
1751 {
1752 if ( !m_xTransGradientTable.is() )
1753 {
1755 }
1756 return m_xTransGradientTable;
1757 }
1758 else if ( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" )
1759 {
1760 if ( !m_xMarkerTable.is() )
1761 {
1763 }
1764 return m_xMarkerTable;
1765 }
1766 }
1767
1768 return nullptr;
1769}
1770
1772{
1773 OSL_ENSURE( Arguments.hasElements(), "ChartView::createInstanceWithArguments: arguments are ignored" );
1774 return createInstance( ServiceSpecifier );
1775}
1776
1778{
1779 uno::Sequence< OUString > aServiceNames{ "com.sun.star.drawing.DashTable",
1780 "com.sun.star.drawing.GradientTable",
1781 "com.sun.star.drawing.HatchTable",
1782 "com.sun.star.drawing.BitmapTable",
1783 "com.sun.star.drawing.TransparencyGradientTable",
1784 "com.sun.star.drawing.MarkerTable" };
1785
1786 return aServiceNames;
1787}
1788
1789OUString ChartView::dump(OUString const & kind)
1790{
1791 if (kind.isEmpty()) {
1792 return dumpXmlToString([this](auto writer) { return dumpAsXml(writer); });
1793 }
1794
1795 // kind == "shapes":
1796#if HAVE_FEATURE_DESKTOP
1797 // Used for unit tests and in chartcontroller only, no need to drag in this when cross-compiling
1798 // for non-desktop
1800 sal_Int32 n = m_xDrawPage->getCount();
1801 OUStringBuffer aBuffer;
1802 for(sal_Int32 i = 0; i < n; ++i)
1803 {
1804 uno::Reference< drawing::XShapes > xShape(m_xDrawPage->getByIndex(i), uno::UNO_QUERY);
1805 if(xShape.is())
1806 {
1808 aBuffer.append(aString);
1809 }
1810 else
1811 {
1812 uno::Reference< drawing::XShape > xSingleShape(m_xDrawPage->getByIndex(i), uno::UNO_QUERY);
1813 if(!xSingleShape.is())
1814 continue;
1815 OUString aString = XShapeDumper::dump(xSingleShape);
1816 aBuffer.append(aString);
1817 }
1818 aBuffer.append("\n\n");
1819 }
1820
1821 return aBuffer.makeStringAndClear();
1822#else
1823 return OUString();
1824#endif
1825}
1826
1828{
1829 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("ChartView"));
1830 (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this);
1831
1833 {
1834 m_pDrawModelWrapper->dumpAsXml(pWriter);
1835 }
1836
1837 (void)xmlTextWriterEndElement(pWriter);
1838}
1839
1841{
1842 std::unique_lock aGuard(maTimeMutex);
1843 m_bViewDirty = true;
1844}
1845
1846IMPL_LINK_NOARG(ChartView, UpdateTimeBased, Timer *, void)
1847{
1848 setViewDirty();
1849 update();
1850}
1851
1852void ChartView::createShapes2D( const awt::Size& rPageSize )
1853{
1854 // todo: it would be nicer to just pass the page m_xDrawPage and format it,
1855 // but the draw page does not support XPropertySet
1856 formatPage( mrChartModel, rPageSize, mxRootShape );
1857
1858 CreateShapeParam2D aParam;
1859 aParam.maRemainingSpace.X = 0;
1860 aParam.maRemainingSpace.Y = 0;
1861 aParam.maRemainingSpace.Width = rPageSize.Width;
1862 aParam.maRemainingSpace.Height = rPageSize.Height;
1863
1864 //create the group shape for diagram and axes first to have title and legends on top of it
1865 rtl::Reference< Diagram > xDiagram( mrChartModel.getFirstChartDiagram() );
1866 bool bHasRelativeSize = false;
1867 if( xDiagram.is() && xDiagram->getPropertyValue("RelativeSize").hasValue() )
1868 bHasRelativeSize = true;
1869
1870 OUString aDiagramCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::number( 0 ) ) );//todo: other index if more than one diagram is possible
1871 rtl::Reference<SvxShapeGroup> xDiagramPlusAxesPlusMarkHandlesGroup_Shapes =
1873
1875 xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0));
1876 ShapeFactory::setShapeName(aParam.mxMarkHandles, "MarkHandles");
1877
1879 xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0, 0));
1880 ShapeFactory::setShapeName(aParam.mxPlotAreaWithAxes, "PlotAreaIncludingAxes");
1881
1882 aParam.mxDiagramWithAxesShapes = ShapeFactory::createGroup2D(xDiagramPlusAxesPlusMarkHandlesGroup_Shapes);
1883
1884 bool bAutoPositionDummy = true;
1885
1886 // create buttons
1887 lcl_createButtons(mxRootShape, mrChartModel, aParam.maRemainingSpace);
1888
1889 lcl_createTitle(
1891 aParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_TOP, bAutoPositionDummy);
1892 if (!bHasRelativeSize && (aParam.maRemainingSpace.Width <= 0 || aParam.maRemainingSpace.Height <= 0))
1893 return;
1894
1895 lcl_createTitle(
1897 aParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_TOP, bAutoPositionDummy );
1898 if (!bHasRelativeSize && (aParam.maRemainingSpace.Width <= 0 || aParam.maRemainingSpace.Height <= 0))
1899 return;
1900
1901 aParam.mpSeriesPlotterContainer = std::make_shared<SeriesPlotterContainer>(m_aVCooSysList);
1902 aParam.mpSeriesPlotterContainer->initializeCooSysAndSeriesPlotter( mrChartModel );
1904 {
1905 auto& rSeriesPlotter = aParam.mpSeriesPlotterContainer->getSeriesPlotterList();
1906 size_t n = rSeriesPlotter.size();
1907 for(size_t i = 0; i < n; ++i)
1908 {
1909 std::vector<VDataSeries*> aAllNewDataSeries = rSeriesPlotter[i]->getAllSeries();
1910 std::vector< VDataSeries* >& rAllOldDataSeries =
1912 size_t m = std::min(aAllNewDataSeries.size(), rAllOldDataSeries.size());
1913 for(size_t j = 0; j < m; ++j)
1914 {
1915 aAllNewDataSeries[j]->setOldTimeBased(
1916 rAllOldDataSeries[j], (maTimeBased.nFrame % 60)/60.0);
1917 }
1918 }
1919 }
1920
1921 lcl_createLegend(
1923 aParam.maRemainingSpace, rPageSize, mrChartModel, aParam.mpSeriesPlotterContainer->getLegendEntryProviderList(),
1924 lcl_getDefaultWritingModeFromPool( m_pDrawModelWrapper ) );
1925
1926 if (!bHasRelativeSize && (aParam.maRemainingSpace.Width <= 0 || aParam.maRemainingSpace.Height <= 0))
1927 return;
1928
1929 if (!createAxisTitleShapes2D(aParam, rPageSize, bHasRelativeSize))
1930 return;
1931
1932 bool bDummy = false;
1933 bool bIsVertical = xDiagram && xDiagram->getVertical(bDummy, bDummy);
1934
1935 if (getAvailablePosAndSizeForDiagram(aParam, rPageSize, xDiagram))
1936 {
1937 awt::Rectangle aUsedOuterRect = impl_createDiagramAndContent(aParam, rPageSize);
1938
1939 if (aParam.mxPlotAreaWithAxes.is())
1940 {
1941 aParam.mxPlotAreaWithAxes->setPosition(awt::Point(aUsedOuterRect.X, aUsedOuterRect.Y));
1942 aParam.mxPlotAreaWithAxes->setSize(awt::Size(aUsedOuterRect.Width, aUsedOuterRect.Height));
1943 }
1944
1945 //correct axis title position
1946 awt::Rectangle aDiagramPlusAxesRect( aUsedOuterRect );
1947 if (aParam.mbAutoPosTitleX)
1948 changePositionOfAxisTitle(aParam.mpVTitleX.get(), TitleAlignment::ALIGN_BOTTOM, aDiagramPlusAxesRect, rPageSize);
1949 if (aParam.mbAutoPosTitleY)
1950 changePositionOfAxisTitle(aParam.mpVTitleY.get(), TitleAlignment::ALIGN_LEFT, aDiagramPlusAxesRect, rPageSize);
1951 if (aParam.mbAutoPosTitleZ)
1952 changePositionOfAxisTitle(aParam.mpVTitleZ.get(), TitleAlignment::ALIGN_Z, aDiagramPlusAxesRect, rPageSize);
1953 if (aParam.mbAutoPosSecondTitleX)
1954 changePositionOfAxisTitle(aParam.mpVTitleSecondX.get(), bIsVertical? TitleAlignment::ALIGN_RIGHT : TitleAlignment::ALIGN_TOP, aDiagramPlusAxesRect, rPageSize);
1955 if (aParam.mbAutoPosSecondTitleY)
1956 changePositionOfAxisTitle(aParam.mpVTitleSecondY.get(), bIsVertical? TitleAlignment::ALIGN_TOP : TitleAlignment::ALIGN_RIGHT, aDiagramPlusAxesRect, rPageSize);
1957 }
1958
1959 //cleanup: remove all empty group shapes to avoid grey border lines:
1960 lcl_removeEmptyGroupShapes( *mxRootShape->GetSdrObject() );
1961
1962 if(maTimeBased.bTimeBased && maTimeBased.nFrame % 60 == 0)
1963 {
1964 // create copy of the data for next frame
1965 auto& rSeriesPlotter = aParam.mpSeriesPlotterContainer->getSeriesPlotterList();
1966 size_t n = rSeriesPlotter.size();
1969 for(size_t i = 0; i < n; ++i)
1970 {
1971 std::vector<VDataSeries*> aAllNewDataSeries = rSeriesPlotter[i]->getAllSeries();
1972 std::vector<VDataSeries*>& rAllOldDataSeries = maTimeBased.m_aDataSeriesList[i];
1973 size_t m = aAllNewDataSeries.size();
1974 for(size_t j = 0; j < m; ++j)
1975 {
1976 rAllOldDataSeries.push_back( aAllNewDataSeries[j]->
1977 createCopyForTimeBased() );
1978 }
1979 }
1980
1982 }
1983
1985 {
1987 maTimeBased.maTimer.SetInvokeHandler(LINK(this, ChartView, UpdateTimeBased));
1989 }
1990}
1991
1992bool ChartView::createAxisTitleShapes2D( CreateShapeParam2D& rParam, const css::awt::Size& rPageSize, bool bHasRelativeSize )
1993{
1994 rtl::Reference<Diagram> xDiagram = mrChartModel.getFirstChartDiagram();
1995
1996 rtl::Reference< ChartType > xChartType;
1997 sal_Int32 nDimension = 0;
1998 if (xDiagram)
1999 {
2000 xChartType = xDiagram->getChartTypeByIndex( 0 );
2001 nDimension = xDiagram->getDimension();
2002 }
2003
2004 if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 0 ) )
2006 , rParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_BOTTOM, rParam.mbAutoPosTitleX );
2007 if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0))
2008 return false;
2009
2010 if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 1 ) )
2012 , rParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_LEFT, rParam.mbAutoPosTitleY );
2013 if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0))
2014 return false;
2015
2016 if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 2 ) )
2018 , rParam.maRemainingSpace, rPageSize, TitleAlignment::ALIGN_RIGHT, rParam.mbAutoPosTitleZ );
2019 if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0))
2020 return false;
2021
2022 bool bDummy = false;
2023 bool bIsVertical = xDiagram && xDiagram->getVertical( bDummy, bDummy );
2024
2025 if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension ) )
2027 , rParam.maRemainingSpace, rPageSize, bIsVertical? TitleAlignment::ALIGN_RIGHT : TitleAlignment::ALIGN_TOP, rParam.mbAutoPosSecondTitleX );
2028 if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0))
2029 return false;
2030
2031 if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension ) )
2033 , rParam.maRemainingSpace, rPageSize, bIsVertical? TitleAlignment::ALIGN_TOP : TitleAlignment::ALIGN_RIGHT, rParam.mbAutoPosSecondTitleY );
2034 if (!bHasRelativeSize && (rParam.maRemainingSpace.Width <= 0 || rParam.maRemainingSpace.Height <= 0))
2035 return false;
2036
2037 return true;
2038}
2039
2040} //namespace chart
2041
2042extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
2044 css::uno::Sequence<css::uno::Any> const &)
2045{
2046 rtl::Reference<::chart::ChartModel> pChartModel = new ::chart::ChartModel(context);
2047 return cppu::acquire(new ::chart::ChartView(context, *pChartModel));
2048}
2049
2050/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_chart2_ChartView_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: ChartView.cxx:2043
AnyEventRef aEvent
FILE * init(int, char **)
void AddDays(sal_Int32 nAddDays)
const SdrPage * GetPage() const
SdrHintKind GetKind() const
SdrObject * GetObj(size_t nNum) const
size_t GetObjCount() const
virtual rtl::Reference< SdrObject > NbcRemoveObject(size_t nObjNum)
virtual css::uno::Reference< css::drawing::XShape > getUnoShape()
virtual SdrObjList * GetSubList() const
virtual const tools::Rectangle & GetSnapRect() const
virtual SdrObjList * getChildrenOfSdrObject() const
virtual void SetSize(const Size &aSiz)
SfxHintId GetId() const
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
OUString GetHexName() const
static bool IsCTLFontEnabled()
bool IsActive() const
void Stop()
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
virtual void Start(bool bStartTimer=true) override
void translate(double fX, double fY, double fZ)
void scale(double fX, double fY, double fZ)
TYPE getMaxX() const
TYPE getWidth() const
TYPE getMinX() const
TYPE getMinY() const
TYPE getMaxY() const
TYPE getHeight() const
static rtl::Reference< ::chart::BaseCoordinateSystem > getCoordinateSystemOfAxis(const rtl::Reference< ::chart::Axis > &xAxis, const rtl::Reference< ::chart::Diagram > &xDiagram)
Definition: AxisHelper.cxx:982
static bool getIndicesForAxis(const rtl::Reference< ::chart::Axis > &xAxis, const rtl::Reference< ::chart::BaseCoordinateSystem > &xCooSys, sal_Int32 &rOutDimensionIndex, sal_Int32 &rOutAxisIndex)
static bool isSupportingMainAxis(const rtl::Reference< ::chart::ChartType > &xChartType, sal_Int32 nDimensionCount, sal_Int32 nDimensionIndex)
static bool isSupportingSecondaryAxis(const rtl::Reference< ::chart::ChartType > &xChartType, sal_Int32 nDimensionCount)
The ChartView is responsible to manage the generation of Drawing Objects for visualization on a given...
Definition: ChartView.hxx:98
bool createAxisTitleShapes2D(CreateShapeParam2D &rParam, const css::awt::Size &rPageSize, bool bHasRelativeSize)
Definition: ChartView.cxx:1992
void impl_updateView(bool bCheckLockedCtrler=true)
Definition: ChartView.cxx:1416
virtual void SAL_CALL updateSoft() override
Definition: ChartView.cxx:1610
void createShapes2D(const css::awt::Size &rPageSize)
Definition: ChartView.cxx:1852
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(const OUString &aServiceSpecifier) override
Definition: ChartView.cxx:1711
virtual bool getExplicitValuesForAxis(rtl::Reference< ::chart::Axis > xAxis, ExplicitScaleData &rExplicitScale, ExplicitIncrementData &rExplicitIncrement) override
Definition: ChartView.cxx:782
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: ChartView.cxx:1693
virtual OUString SAL_CALL getImplementationName() override
Definition: ChartView.cxx:312
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: ChartView.cxx:322
virtual ~ChartView() override
Definition: ChartView.cxx:201
comphelper::OInterfaceContainerHelper4< css::util::XModeChangeListener > m_aModeChangeListeners
Definition: ChartView.hxx:229
chart::ChartModel & mrChartModel
Definition: ChartView.hxx:208
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: ChartView.cxx:1699
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: ChartView.cxx:1497
bool m_bViewUpdatePending
Definition: ChartView.hxx:233
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: ChartView.cxx:1704
rtl::Reference< SvxShapeGroupAnyD > mxRootShape
Definition: ChartView.hxx:215
virtual void SAL_CALL removeModeChangeApproveListener(const css::uno::Reference< css::util::XModeChangeApproveListener > &_rxListener) override
Definition: ChartView.cxx:1591
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: ChartView.cxx:317
css::awt::Size m_aPageResolution
Definition: ChartView.hxx:237
sal_Int32 m_nScaleYDenominator
Definition: ChartView.hxx:244
virtual rtl::Reference< SvxShape > getShapeForCID(const OUString &rObjectCID) override
Definition: ChartView.cxx:843
std::mutex m_aMutex
Definition: ChartView.hxx:204
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: ChartView.cxx:1688
virtual css::awt::Rectangle getDiagramRectangleExcludingAxes() override
Definition: ChartView.cxx:856
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: ChartView.cxx:1827
void impl_refreshAddIn()
Definition: ChartView.cxx:1329
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: ChartView.cxx:1621
virtual void SAL_CALL addModeChangeApproveListener(const css::uno::Reference< css::util::XModeChangeApproveListener > &_rxListener) override
Definition: ChartView.cxx:1587
virtual void SAL_CALL addModeChangeListener(const css::uno::Reference< css::util::XModeChangeListener > &_rxListener) override
Definition: ChartView.cxx:1577
css::awt::Rectangle m_aResultingDiagramRectangleExcludingAxes
Definition: ChartView.hxx:248
sal_Int32 m_nScaleXNumerator
Definition: ChartView.hxx:241
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments(const OUString &ServiceSpecifier, const css::uno::Sequence< css::uno::Any > &Arguments) override
Definition: ChartView.cxx:1771
virtual void SAL_CALL modified(const css::lang::EventObject &aEvent) override
Definition: ChartView.cxx:1487
css::uno::Reference< css::lang::XMultiServiceFactory > m_xShapeFactory
Definition: ChartView.hxx:211
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: ChartView.cxx:1627
css::uno::Reference< css::uno::XComponentContext > const & getComponentContext()
Definition: ChartView.hxx:180
css::uno::Reference< css::uno::XInterface > m_xHatchTable
Definition: ChartView.hxx:219
SdrPage * getSdrPage()
Definition: ChartView.cxx:835
css::uno::Reference< css::uno::XInterface > m_xGradientTable
Definition: ChartView.hxx:218
virtual css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor &aFlavor) override
Definition: ChartView.cxx:273
std::shared_ptr< DrawModelWrapper > getDrawModelWrapper() override
Definition: ChartView.cxx:912
bool m_bPointsWereSkipped
Definition: ChartView.hxx:238
sal_Int32 m_nScaleXDenominator
Definition: ChartView.hxx:242
css::uno::Reference< css::uno::XInterface > m_xMarkerTable
Definition: ChartView.hxx:222
std::shared_ptr< DrawModelWrapper > m_pDrawModelWrapper
Definition: ChartView.hxx:224
virtual void SAL_CALL updateHard() override
Definition: ChartView.cxx:1615
css::uno::Reference< css::uno::XComponentContext > m_xCC
Definition: ChartView.hxx:206
void getMetaFile(const css::uno::Reference< css::io::XOutputStream > &xOutStream, bool bUseHighContrast)
Definition: ChartView.cxx:235
void impl_deleteCoordinateSystems()
Definition: ChartView.cxx:220
css::uno::Reference< css::uno::XInterface > m_xBitmapTable
Definition: ChartView.hxx:220
std::mutex maTimeMutex
Definition: ChartView.hxx:251
bool m_bSdrViewIsInEditMode
Definition: ChartView.hxx:246
css::uno::Reference< css::uno::XInterface > m_xTransGradientTable
Definition: ChartView.hxx:221
std::vector< std::unique_ptr< VCoordinateSystem > > m_aVCooSysList
Definition: ChartView.hxx:226
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &aArguments) override
Definition: ChartView.cxx:196
virtual css::awt::Rectangle getRectangleOfObject(const OUString &rObjectCID, bool bSnapRect=false) override
Definition: ChartView.cxx:862
virtual css::uno::Sequence< OUString > SAL_CALL getAvailableServiceNames() override
Definition: ChartView.cxx:1777
TimeBasedInfo maTimeBased
Definition: ChartView.hxx:250
virtual css::uno::Sequence< css::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors() override
Definition: ChartView.cxx:296
virtual void SAL_CALL removeModeChangeListener(const css::uno::Reference< css::util::XModeChangeListener > &_rxListener) override
Definition: ChartView.cxx:1582
void impl_notifyModeChangeListener(const OUString &rNewMode)
Definition: ChartView.cxx:1558
virtual sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor &aFlavor) override
Definition: ChartView.cxx:304
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
Definition: ChartView.cxx:1412
css::awt::Rectangle impl_createDiagramAndContent(const CreateShapeParam2D &rParam, const css::awt::Size &rPageSize)
Definition: ChartView.cxx:499
rtl::Reference< SvxDrawPage > m_xDrawPage
Definition: ChartView.hxx:213
sal_Int32 m_nScaleYNumerator
Definition: ChartView.hxx:243
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: ChartView.cxx:1680
virtual OUString SAL_CALL dump(OUString const &kind) override
Definition: ChartView.cxx:1789
ChartView()=delete
css::uno::Reference< css::uno::XInterface > m_xDashTable
Definition: ChartView.hxx:217
virtual void SAL_CALL update() override
Definition: ChartView.cxx:1597
static Date GetDateSomeYearsAway(const Date &rD, sal_Int32 nYearDistance)
Definition: DateHelper.cxx:46
static Date GetDateSomeMonthsAway(const Date &rD, sal_Int32 nMonthDistance)
Definition: DateHelper.cxx:39
static bool switchDiagramPositioningToExcludingPositioning(ChartModel &rModel, bool bResetModifiedState, bool bConvertAlsoFromAutoPositioning)
SdrObject * getNamedSdrObject(const OUString &rName)
static rtl::Reference< ::chart::Legend > getLegend(ChartModel &rModel, const css::uno::Reference< css::uno::XComponentContext > &xContext=nullptr, bool bCreate=false)
static OUString createClassifiedIdentifier(enum ObjectType eObjectType, std::u16string_view rParticleID)
ObjectType getObjectType() const
static OUString createClassifiedIdentifierForObject(const css::uno::Reference< css::uno::XInterface > &xObject, const rtl::Reference<::chart::ChartModel > &xChartModel)
virtual void setTransformationSceneToScreen(const css::drawing::HomogenMatrix &rMatrix)
Definition: PlotterBase.cxx:60
virtual void createShapes()=0
virtual void initPlotter(const rtl::Reference< SvxShapeGroupAnyD > &xLogicTarget, const rtl::Reference< SvxShapeGroupAnyD > &xFinalTarget, const OUString &rCID)
Definition: PlotterBase.cxx:36
static const tPropertyNameMap & getPropertyNameMapForFillAndLineProperties()
static void getMultiPropertyListsFromValueMap(tNameSequence &rNames, tAnySequence &rValues, const tPropertyNameValueMap &rValueMap)
static void getValueMap(tPropertyNameValueMap &rValueMap, const tPropertyNameMap &rNameMap, const css::uno::Reference< css::beans::XPropertySet > &xSourceProp)
Fetch property values from the source object and map it to the destination container.
static css::awt::Point getUpperLeftCornerOfAnchoredObject(css::awt::Point aPoint, css::awt::Size aObjectSize, css::drawing::Alignment aAnchor)
returns the upper left corner of an object that has size aObjectSize and where the point indicated by...
static css::awt::Point getCenterOfAnchoredObject(css::awt::Point aPoint, css::awt::Size aUnrotatedObjectSize, css::drawing::Alignment aAnchor, double fAnglePi)
returns the center of an object that has size aObjectSize and where the point indicated by aAnchor ha...
static VCoordinateSystem * getCooSysForPlotter(const std::vector< std::unique_ptr< VCoordinateSystem > > &rVCooSysList, MinimumAndMaximumSupplier *pMinimumAndMaximumSupplier)
static VCoordinateSystem * findInCooSysList(const std::vector< std::unique_ptr< VCoordinateSystem > > &rVCooSysList, const rtl::Reference< BaseCoordinateSystem > &xCooSys)
static void setShapeName(const rtl::Reference< SvxShape > &xShape, const OUString &rName)
static rtl::Reference< SvxShapeGroupAnyD > getOrCreateChartRootShape(const rtl::Reference< SvxDrawPage > &xPage)
static void setPageSize(const rtl::Reference< SvxShapeGroupAnyD > &xChartShapes, const css::awt::Size &rSize)
static rtl::Reference< SvxShapeRect > createRectangle(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::awt::Size &rSize, const css::awt::Point &rPosition, const tNameSequence &rPropNames, const tAnySequence &rPropValues, StackPosition ePos=StackPosition::Top)
static rtl::Reference< SvxShapeRect > createInvisibleRectangle(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const css::awt::Size &rSize)
static void removeSubShapes(const rtl::Reference< SvxShapeGroupAnyD > &xShapes)
static rtl::Reference< SvxShapeGroup > createGroup2D(const rtl::Reference< SvxShapeGroupAnyD > &xTarget, const OUString &aName=OUString())
::basegfx::B2IRectangle getRectangleOfShape(SvxShape &rShape)
static CuboidPlanePosition getAutomaticCuboidPlanePositionForStandardBackWall(const rtl::Reference< ::chart::Diagram > &xDiagram)
static CuboidPlanePosition getAutomaticCuboidPlanePositionForStandardLeftWall(const rtl::Reference< ::chart::Diagram > &xDiagram)
static CuboidPlanePosition getAutomaticCuboidPlanePositionForStandardBottom(const rtl::Reference< ::chart::Diagram > &xDiagram)
static rtl::Reference< ::chart::Title > getTitle(eTitleType nTitleIndex, ChartModel &rModel)
static OUString getCompleteString(const rtl::Reference< ::chart::Title > &xTitle)
ExplicitScaleData getExplicitScale(sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex) const
ExplicitIncrementData getExplicitIncrement(sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex) const
void setTransformationSceneToScreen(const css::drawing::HomogenMatrix &rMatrix)
virtual css::uno::Sequence< sal_Int32 > getCoordinateSystemResolution(const css::awt::Size &rPageSize, const css::awt::Size &rPageResolution)
const css::drawing::HomogenMatrix & getTransformationSceneToScreen() const
The VDiagram is responsible to generate the visible parts of the Diagram that is wall,...
Definition: VDiagram.hxx:46
void reduceToMinimumSize()
Definition: VDiagram.cxx:634
basegfx::B2IRectangle getCurrentRectangle() const
Get current bounding rectangle for the diagram without axes.
Definition: VDiagram.cxx:629
::basegfx::B2IRectangle adjustInnerSize(const ::basegfx::B2IRectangle &rConsumedOuterRect)
Definition: VDiagram.cxx:652
const rtl::Reference< SvxShapeGroupAnyD > & getCoordinateRegion() const
Definition: VDiagram.hxx:60
void createShapes(const css::awt::Point &rPos, const css::awt::Size &rSize)
Definition: VDiagram.cxx:80
void init(const rtl::Reference< SvxShapeGroupAnyD > &xTarget)
Definition: VDiagram.cxx:75
static bool isVisible(const rtl::Reference< ::chart::Legend > &xLegend)
Definition: VLegend.cxx:903
bool PointsWereSkipped() const
void setAvailableOuterRect(const basegfx::B2IRectangle &aAvailableOuterRect)
void setPageReferenceSize(const css::awt::Size &rPageRefSize)
void setCoordinateSystemResolution(const css::uno::Sequence< sal_Int32 > &rCoordinateSystemResolution)
void setPieLabelsAllowToMove(bool bIsPieOrDonut)
static bool isVisible(const rtl::Reference< ::chart::Title > &xTitle)
Definition: VTitle.cxx:95
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(std::unique_lock< std::mutex > &rGuard, void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event) const
sal_Int32 getLength(std::unique_lock< std::mutex > &rGuard) const
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
constexpr tools::Long GetWidth() const
constexpr tools::Long Top() const
constexpr tools::Long GetHeight() const
constexpr tools::Long Left() const
int nCount
constexpr double FIXED_SIZE_FOR_3D_CHART_VOLUME
Definition: defines.hxx:22
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
float x
Sequence< OUString > aServiceNames
#define SOFFICE_FILEFORMAT_50
struct _xmlTextWriter * xmlTextWriterPtr
ALIGN_BOTTOM
ALIGN_TOP
SvxFrameDirection
sal_Int64 n
Sequence< sal_Int8 > aSeq
OOO_DLLPUBLIC_CHARTTOOLS::basegfx::B2IRectangle makeRectangle(const css::awt::Point &rPosition, const css::awt::Size &rSize)
OOO_DLLPUBLIC_CHARTTOOLS css::awt::Rectangle toAwtRectangle(const basegfx::B2IRectangle &rB2IRectangle)
@ OBJECTTYPE_DIAGRAM
css::uno::Sequence< OUString > tNameSequence
OUString dumpXmlToString(F f)
css::uno::Sequence< css::uno::Any > tAnySequence
::basegfx::B3DHomMatrix createTransformationSceneToScreen(const ::basegfx::B2IRectangle &rDiagramRectangleWithoutAxes)
Definition: ChartView.cxx:327
OOO_DLLPUBLIC_CHARTTOOLS css::drawing::HomogenMatrix B3DHomMatrixToHomogenMatrix(const ::basegfx::B3DHomMatrix &rM)
diverse methods for class conversions; e.g.
std::unordered_map< OUString, css::uno::Any > tPropertyNameValueMap
CuboidPlanePosition
IMPL_LINK_NOARG(SplinePropertiesDialog, SplineTypeListBoxHdl, weld::ComboBox &, void)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
m
long Long
const char GetValue[]
constexpr OUStringLiteral CHART_VIEW_SERVICE_NAME
constexpr OUStringLiteral CHART_VIEW_SERVICE_IMPLEMENTATION_NAME
constexpr OUStringLiteral CHART2_SERVICE_NAME_CHARTTYPE_PIE
static OUString dump(const css::uno::Reference< css::drawing::XShapes > &xPageShapes, bool bDumpInteropProperties=false)
std::shared_ptr< VTitle > mpVTitleSecondY
Definition: ChartView.cxx:136
rtl::Reference< SvxShapeRect > mxPlotAreaWithAxes
Definition: ChartView.cxx:139
rtl::Reference< SvxShapeGroup > mxDiagramWithAxesShapes
Definition: ChartView.cxx:141
rtl::Reference< SvxShapeRect > mxMarkHandles
Definition: ChartView.cxx:138
std::shared_ptr< VTitle > mpVTitleSecondX
Definition: ChartView.cxx:135
std::shared_ptr< VTitle > mpVTitleX
Definition: ChartView.cxx:131
std::shared_ptr< VTitle > mpVTitleZ
Definition: ChartView.cxx:133
std::shared_ptr< SeriesPlotterContainer > mpSeriesPlotterContainer
Definition: ChartView.cxx:129
std::shared_ptr< VTitle > mpVTitleY
Definition: ChartView.cxx:132
css::awt::Rectangle maRemainingSpace
Definition: ChartView.cxx:127
describes how tickmarks are positioned on the scale of an axis.
This structure contains the explicit values for a scale like Minimum and Maximum.
std::vector< std::vector< VDataSeries * > > m_aDataSeriesList
Definition: ChartView.hxx:73
unsigned char sal_Bool
SVXCORE_DLLPUBLIC css::uno::Reference< css::uno::XInterface > SvxUnoDashTable_createInstance(SdrModel *pModel)
SVXCORE_DLLPUBLIC css::uno::Reference< css::uno::XInterface > SvxUnoGradientTable_createInstance(SdrModel *pModel)
SVXCORE_DLLPUBLIC css::uno::Reference< css::uno::XInterface > SvxUnoBitmapTable_createInstance(SdrModel *pModel)
SVXCORE_DLLPUBLIC css::uno::Reference< css::uno::XInterface > SvxUnoMarkerTable_createInstance(SdrModel *pModel)
SVXCORE_DLLPUBLIC css::uno::Reference< css::uno::XInterface > SvxUnoHatchTable_createInstance(SdrModel *pModel)
SVXCORE_DLLPUBLIC css::uno::Reference< css::uno::XInterface > SvxUnoTransGradientTable_createInstance(SdrModel *pModel)
bool update()
std::unique_ptr< char[]> aBuffer