[Libreoffice-commits] core.git: chart2/qa include/oox oox/source

Balazs Varga (via logerrit) logerrit at kemper.freedesktop.org
Tue Oct 1 09:20:05 UTC 2019


 chart2/qa/extras/chart2export.cxx            |   11 +++++
 chart2/qa/extras/data/xlsx/tdf127777.xlsx    |binary
 include/oox/export/chartexport.hxx           |    1 
 oox/source/drawingml/chart/axisconverter.cxx |    2 
 oox/source/export/chartexport.cxx            |   56 +++++++++++++++++++++++----
 5 files changed, 63 insertions(+), 7 deletions(-)

New commits:
commit 6027ec08fd5df2e09e34ff61b3777ad2cc8304b3
Author:     Balazs Varga <balazs.varga991 at gmail.com>
AuthorDate: Fri Sep 27 14:29:49 2019 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Tue Oct 1 11:19:18 2019 +0200

    tdf#127777 OOXML chart export: fix X axis position setting "CrossBetween"
    
    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 <nemeth at numbertext.org>

diff --git a/chart2/qa/extras/chart2export.cxx b/chart2/qa/extras/chart2export.cxx
index e1c7a4403afe..2589428831bc 100644
--- a/chart2/qa/extras/chart2export.cxx
+++ b/chart2/qa/extras/chart2export.cxx
@@ -120,6 +120,7 @@ public:
     void testSetSeriesToSecondaryAxisXLSX();
     void testCombinedChartSecondaryAxisXLSX();
     void testCombinedChartSecondaryAxisODS();
+    void testCrossBetweenXLSX();
     void testAxisTitleRotationXLSX();
     void testAxisCrossBetweenXSLX();
     void testPieChartDataPointExplosionXLSX();
@@ -223,6 +224,7 @@ public:
     CPPUNIT_TEST(testSetSeriesToSecondaryAxisXLSX);
     CPPUNIT_TEST(testCombinedChartSecondaryAxisXLSX);
     CPPUNIT_TEST(testCombinedChartSecondaryAxisODS);
+    CPPUNIT_TEST(testCrossBetweenXLSX);
     CPPUNIT_TEST(testAxisTitleRotationXLSX);
     CPPUNIT_TEST(testAxisCrossBetweenXSLX);
     CPPUNIT_TEST(testPieChartDataPointExplosionXLSX);
@@ -1901,6 +1903,15 @@ void Chart2ExportTest::testCombinedChartSecondaryAxisODS()
     assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:catAx[2]/c:crosses", 0);
 }
 
+void Chart2ExportTest::testCrossBetweenXLSX()
+{
+    // Original file was created with MS Office
+    load("/chart2/qa/extras/data/xlsx/", "tdf127777.xlsx");
+    xmlDocPtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML");
+    CPPUNIT_ASSERT(pXmlDoc);
+    assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx/c:crossBetween", "val", "between");
+}
+
 void Chart2ExportTest::testAxisTitleRotationXLSX()
 {
     load("/chart2/qa/extras/data/xlsx/", "axis_title_rotation.xlsx");
diff --git a/chart2/qa/extras/data/xlsx/tdf127777.xlsx b/chart2/qa/extras/data/xlsx/tdf127777.xlsx
new file mode 100644
index 000000000000..c04de30fc8e2
Binary files /dev/null and b/chart2/qa/extras/data/xlsx/tdf127777.xlsx differ
diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx
index e7474d75ac15..304bd620d1af 100644
--- a/include/oox/export/chartexport.hxx
+++ b/include/oox/export/chartexport.hxx
@@ -106,6 +106,7 @@ private:
 
     // members filled by InitRangeSegmentationProperties (retrieved from DataProvider)
     bool mbHasCategoryLabels; //if the categories are only automatically generated this will be false
+    bool mbIsCategoryPositionShifted; //if the value axis crosses the category axis between tickmarks this will be true
 
     //css::uno::Reference< css::drawing::XShapes > mxAdditionalShapes;
     css::uno::Reference< css::chart2::data::XDataSequence > mxCategoriesValues;
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


More information about the Libreoffice-commits mailing list