From 6027ec08fd5df2e09e34ff61b3777ad2cc8304b3 Mon Sep 17 00:00:00 2001 From: Balazs Varga Date: Fri, 27 Sep 2019 14:29:49 +0200 Subject: tdf#127777 OOXML chart export: fix X axis position setting "CrossBetween" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Export ShiftedCategoryPosition value into the CrossBetween OOXML tag. Change-Id: I3d8b298ed47c5326ee4faf0e8663c8c79d5a1d86 Reviewed-on: https://gerrit.libreoffice.org/79502 Tested-by: Jenkins Reviewed-by: László Németh --- oox/source/drawingml/chart/axisconverter.cxx | 2 + oox/source/export/chartexport.cxx | 56 ++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 7 deletions(-) (limited to 'oox') diff --git a/oox/source/drawingml/chart/axisconverter.cxx b/oox/source/drawingml/chart/axisconverter.cxx index 9f2cc0f715dc..0f6973b02ec4 100644 --- a/oox/source/drawingml/chart/axisconverter.cxx +++ b/oox/source/drawingml/chart/axisconverter.cxx @@ -224,6 +224,8 @@ void AxisConverter::convertFromModel( case API_Y_AXIS: OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( valAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:valAx)" ); aScaleData.AxisType = isPercent(rTypeGroups) ? cssc2::AxisType::PERCENT : cssc2::AxisType::REALNUMBER; + if( mrModel.mnCrossBetween != -1 ) + aScaleData.ShiftedCategoryPosition = mrModel.mnCrossBetween == XML_between; break; case API_Z_AXIS: OSL_ENSURE( mrModel.mnTypeId == C_TOKEN( serAx ), "AxisConverter::convertFromModel - unexpected axis model type (must: c:serAx)" ); diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index c282b0d9263f..5e23e68cb631 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -227,6 +227,48 @@ static bool lcl_hasCategoryLabels( const Reference< chart2::XChartDocument >& xC return xCategories.is(); } +static bool lcl_isCategoryAxisShifted(const Reference< chart2::XChartDocument >& xChartDoc) +{ + Reference< chart2::XDiagram > xDiagram(xChartDoc->getFirstDiagram()); + bool isCategoryPositionShifted = false; + + try + { + Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( + xDiagram, uno::UNO_QUERY_THROW); + const Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq( + xCooSysCnt->getCoordinateSystems()); + for( const auto& xCooSys : aCooSysSeq ) + { + OSL_ASSERT(xCooSys.is()); + for( sal_Int32 nN = xCooSys->getDimension(); nN--; ) + { + const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN); + for( sal_Int32 nI = 0; nI <= nMaxAxisIndex; ++nI ) + { + Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension(nN, nI); + OSL_ASSERT(xAxis.is()); + if( xAxis.is()) + { + chart2::ScaleData aScaleData = xAxis->getScaleData(); + if( aScaleData.AxisType == AXIS_PRIMARY_Y ) + { + isCategoryPositionShifted = aScaleData.ShiftedCategoryPosition; + break; + } + } + } + } + } + } + catch (const uno::Exception &) + { + DBG_UNHANDLED_EXCEPTION("oox"); + } + + return isCategoryPositionShifted; +} + static bool lcl_isSeriesAttachedToFirstAxis( const Reference< chart2::XDataSeries > & xDataSeries ) { @@ -735,6 +777,7 @@ void ChartExport::InitRangeSegmentationProperties( const Reference< chart2::XCha if( xDataProvider.is()) { mbHasCategoryLabels = lcl_hasCategoryLabels( xChartDoc ); + mbIsCategoryPositionShifted = lcl_isCategoryAxisShifted( xChartDoc ); } } catch( const uno::Exception & ) @@ -2902,14 +2945,13 @@ void ChartExport::_exportAxis( pFS->singleElement(FSNS(XML_c, XML_noMultiLvlLbl), XML_val, OString::number(0)); } - // TODO: MSO does not support random axis cross position for - // category axis, so we ideally need an algorithm that decides - // when to map the crossing to the tick mark and when to the - // middle of the category - sal_Int32 nChartType = getChartType(); - if (nAxisType == XML_valAx && (nChartType == chart::TYPEID_LINE || nChartType == chart::TYPEID_SCATTER)) + // crossBetween + if( nAxisType == XML_valAx ) { - pFS->singleElement(FSNS(XML_c, XML_crossBetween), XML_val, "midCat"); + if( mbIsCategoryPositionShifted ) + pFS->singleElement(FSNS(XML_c, XML_crossBetween), XML_val, "between"); + else + pFS->singleElement(FSNS(XML_c, XML_crossBetween), XML_val, "midCat"); } // majorUnit -- cgit