/** 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 havetobeinsertedintoonecoordinatesystem.Later,chart2should
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 buggyhere,theXMLpluginofMSO2003writesthecorrectperspectivein
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.