/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
/** Axes set model. This is a helper for the plot area converter collecting all
type groups and axes of the primary or secondary axes set. */ struct AxesSetModel
{ typedef ModelVector< TypeGroupModel > TypeGroupVector; typedef ModelMap< sal_Int32, AxisModel > AxisMap;
TypeGroupVector maTypeGroups; /// All type groups containing data series.
AxisMap maAxes; /// All axes mapped by API axis type.
explicit AxesSetModel() {}
};
/** Axes set converter. This is a helper class for the plot area converter. */ class AxesSetConverter : public ConverterBase< AxesSetModel >
{ public: explicit AxesSetConverter( const ConverterRoot& rParent, AxesSetModel& rModel );
/** Converts the axes set model to a chart2 diagram. Returns an automatic
chart title from a single series title, if possible. */ void convertFromModel( const Reference< XDiagram >& rxDiagram,
View3DModel& rView3DModel,
sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint, bool bUseFixedInnerSize );
/** Returns the automatic chart title if the axes set contains only one series. */ const OUString& getAutomaticTitle() const { return maAutoTitle; } /** Returns true, if the chart contains only one series and have title textbox (even empty). */ bool isSingleSeriesTitle() const { return mbSingleSeriesTitle; } /** Returns true, if the chart is three-dimensional. */ bool is3dChart() const { return mb3dChart; } /** Returns true, if chart type supports wall and floor format in 3D mode. */ bool isWall3dChart() const { return mbWall3dChart; } /** Returns true, if chart is a pie chart or doughnut chart. */ bool isPieChart() const { return mbPieChart; }
void AxesSetConverter::convertFromModel( const Reference< XDiagram >& rxDiagram,
View3DModel& rView3DModel, sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint, bool bUseFixedInnerSize)
{ // create type group converter objects for all type groups typedef RefVector< TypeGroupConverter > TypeGroupConvVector;
TypeGroupConvVector aTypeGroups; for (autoconst& typeGroup : mrModel.maTypeGroups)
aTypeGroups.push_back( std::make_shared<TypeGroupConverter>( *this, *typeGroup ) );
OSL_ENSURE( !aTypeGroups.empty(), "AxesSetConverter::convertFromModel - no type groups in axes set" ); if( aTypeGroups.empty() ) return;
try
{ // first type group needed for coordinate system and axis conversion
TypeGroupConverter& rFirstTypeGroup = *aTypeGroups.front();
// get automatic chart title, if there is only one type group if( aTypeGroups.size() == 1 )
{
maAutoTitle = rFirstTypeGroup.getSingleSeriesTitle();
mbSingleSeriesTitle = rFirstTypeGroup.isSingleSeriesTitle();
}
/* Create a coordinate system. For now, all type groups from all axes sets have to be inserted into one coordinate system. Later, chart2 should
support using one coordinate system for each axes set. */
Reference< XCoordinateSystem > xCoordSystem;
Reference< XCoordinateSystemContainer > xCoordSystemCont( rxDiagram, UNO_QUERY_THROW );
Sequence< Reference< XCoordinateSystem > > aCoordSystems = xCoordSystemCont->getCoordinateSystems(); if( aCoordSystems.hasElements() )
{
OSL_ENSURE( aCoordSystems.getLength() == 1, "AxesSetConverter::convertFromModel - too many coordinate systems" );
xCoordSystem = aCoordSystems[ 0 ];
OSL_ENSURE( xCoordSystem.is(), "AxesSetConverter::convertFromModel - invalid coordinate system" );
} else
{
xCoordSystem = rFirstTypeGroup.createCoordinateSystem(); if( xCoordSystem.is() )
xCoordSystemCont->addCoordinateSystem( xCoordSystem );
}
// convert all chart type groups, this converts all series data and formatting for (autoconst& typeGroup : aTypeGroups)
typeGroup->convertFromModel( rxDiagram, xCoordSystem, nAxesSetIdx, bSupportsVaryColorsByPoint );
}
} catch( Exception& )
{
}
}
if( rTypeGroup.getTypeInfo().meTypeCategory == TYPECATEGORY_PIE )
{ // Y rotation used as 'first pie slice angle' in 3D pie charts
rTypeGroup.convertPieRotation( aPropSet, mrModel.monRotationY.value_or( 0 ) ); // X rotation a.k.a. elevation (map OOXML [0..90] to Chart2 [-90,0])
nRotationX = getLimitedValue< sal_Int32, sal_Int32 >( mrModel.monRotationX.value_or( 15 ), 0, 90 ) - 90; // no right-angled axes in pie charts
bRightAngled = false; // ambient color (Gray 30%)
nAmbientColor = 0xB3B3B3; // light color (Gray 70%)
nLightColor = 0x4C4C4C;
} else// 3D bar/area/line charts
{ // Y rotation (OOXML [0..359], Chart2 [-179,180])
nRotationY = mrModel.monRotationY.value_or( 20 ); // X rotation a.k.a. elevation (OOXML [-90..90], Chart2 [-179,180])
nRotationX = getLimitedValue< sal_Int32, sal_Int32 >( mrModel.monRotationX.value_or( 15 ), -90, 90 ); // right-angled axes
bRightAngled = mrModel.mbRightAngled; // ambient color (Gray 20%)
nAmbientColor = 0xCCCCCC; // light color (Gray 60%)
nLightColor = 0x666666;
}
// Y rotation (map OOXML [0..359] to Chart2 [-179,180])
nRotationY = NormAngle180(nRotationY); /* Perspective (map OOXML [0..200] to Chart2 [0,100]). Seems that MSO 2007 is buggy here, the XML plugin of MSO 2003 writes the correct perspective in
the range from 0 to 100. We will emulate the wrong behaviour of MSO 2007. */
sal_Int32 nPerspective = getLimitedValue< sal_Int32, sal_Int32 >( mrModel.mnPerspective / 2, 0, 100 ); // projection mode (parallel axes, if right-angled, #i90360# or if perspective is at 0%) bool bParallel = bRightAngled || (nPerspective == 0);
cssd::ProjectionMode eProjMode = bParallel ? cssd::ProjectionMode_PARALLEL : cssd::ProjectionMode_PERSPECTIVE;
void PlotAreaConverter::convertFromModel( View3DModel& rView3DModel )
{ /* Create the diagram object and attach it to the chart document. One
diagram is used to carry all coordinate systems and data series. */
Reference< XDiagram > xDiagram; try
{
xDiagram.set( createInstance( u"com.sun.star.chart2.Diagram"_ustr ), UNO_QUERY_THROW );
getChartDocument()->setFirstDiagram( xDiagram );
} catch( Exception& )
{
}
// store all axis models in a map, keyed by axis identifier typedef ModelMap< sal_Int32, AxisModel > AxisMap;
AxisMap aAxisMap;
std::vector<sal_Int32>rValAxisIds;
std::vector<sal_Int32>rRealValAxisIds;
for (autoconst& atypeGroup : mrModel.maTypeGroups)
{ if (atypeGroup->maAxisIds.size() > 1)
{ // let's collect which axId belongs to the Y Axis according to maTypeGroups
rRealValAxisIds.push_back(atypeGroup->maAxisIds[1]);
}
}
if ( axis->mnAxisId != -1 && axis->mnTypeId == C_TOKEN(valAx) )
{ for (size_t i = 0; i < rRealValAxisIds.size(); i++)
{ if (axis->mnAxisId == rRealValAxisIds[i])
{ // let's collect which axId belongs to the Y Axis according to maAxes
rValAxisIds.push_back(axis->mnAxisId);
}
}
}
}
// group the type group models into different axes sets typedef ModelVector< AxesSetModel > AxesSetVector;
AxesSetVector aAxesSets;
sal_Int32 nMaxSeriesIdx = -1; for (autoconst& typeGroup : mrModel.maTypeGroups)
{ if( !typeGroup->maSeries.empty() )
{ // try to find a compatible axes set for the type group
AxesSetModel* pAxesSet = nullptr; for (autoconst& axesSet : aAxesSets)
{ if( axesSet->maTypeGroups.front()->maAxisIds == typeGroup->maAxisIds )
{
pAxesSet = axesSet.get(); if (pAxesSet) break;
}
}
// not possible to insert into an existing axes set -> start a new axes set if( !pAxesSet )
{
pAxesSet = &aAxesSets.create(); // find axis models used by the type group const std::vector<sal_Int32>& rAxisIds = typeGroup->maAxisIds; if( !rAxisIds.empty() )
pAxesSet->maAxes[ API_X_AXIS ] = aAxisMap.get( rAxisIds[ 0 ] ); if( rAxisIds.size() >= 2 )
pAxesSet->maAxes[ API_Y_AXIS ] = aAxisMap.get( rAxisIds[ 1 ] ); if( rAxisIds.size() >= 3 )
pAxesSet->maAxes[ API_Z_AXIS ] = aAxisMap.get( rAxisIds[ 2 ] );
}
// insert the type group model
pAxesSet->maTypeGroups.push_back( typeGroup );
// collect the maximum series index for automatic series formatting for (autoconst& elemSeries : typeGroup->maSeries)
nMaxSeriesIdx = ::std::max( nMaxSeriesIdx, elemSeries->mnIndex );
}
}
getFormatter().setMaxSeriesIndex( nMaxSeriesIdx );
// varying point colors only for single series in single chart type bool bSupportsVaryColorsByPoint = mrModel.maTypeGroups.size() == 1;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.