chart2/qa/extras/chart2dump/chart2dump.cxx                              |    1 
 chart2/qa/extras/chart2dump/data/date-categories.pptx                   |binary
 chart2/qa/extras/chart2dump/reference/axislabeltest/date-categories.txt |  180 
++++++++++
 chart2/qa/extras/chart2export.cxx                                       |   40 
++
 chart2/qa/extras/chart2import.cxx                                       |   46 
+-
 chart2/qa/extras/charttest.hxx                                          |   37 
++
 chart2/source/inc/InternalDataProvider.hxx                              |    6 
 chart2/source/tools/InternalDataProvider.cxx                            |   20 
-
 chart2/source/view/axes/ScaleAutomatism.cxx                             |    4 
 chart2/source/view/axes/VCoordinateSystem.cxx                           |    6 
 chart2/source/view/charttypes/AreaChart.cxx                             |    4 
 dbaccess/source/core/inc/DatabaseDataProvider.hxx                       |    2 
 dbaccess/source/core/misc/DatabaseDataProvider.cxx                      |    2 
 include/oox/drawingml/chart/chartconverter.hxx                          |    3 
 include/oox/drawingml/chart/datasourcemodel.hxx                         |    3 
 include/oox/export/chartexport.hxx                                      |    1 
 offapi/com/sun/star/chart2/data/XDataProvider.idl                       |   23 
+
 oox/source/drawingml/chart/chartconverter.cxx                           |    4 
 oox/source/drawingml/chart/datasourcecontext.cxx                        |   23 
-
 oox/source/drawingml/chart/datasourceconverter.cxx                      |    6 
 oox/source/drawingml/chart/datasourcemodel.cxx                          |    4 
 oox/source/export/chartexport.cxx                                       |   43 
++
 sc/inc/PivotTableDataProvider.hxx                                       |    3 
 sc/inc/chart2uno.hxx                                                    |    3 
 sc/source/filter/inc/excelchartconverter.hxx                            |    3 
 sc/source/filter/oox/excelchartconverter.cxx                            |    2 
 sc/source/ui/unoobj/PivotTableDataProvider.cxx                          |    3 
 sc/source/ui/unoobj/chart2uno.cxx                                       |    3 
 sw/inc/unochart.hxx                                                     |    2 
 sw/source/core/unocore/unochart.cxx                                     |    3 
 30 files changed, 413 insertions(+), 67 deletions(-)

New commits:
commit 3798e0a383404606ec27f318e4fe239de2350fe8
Author:     Dennis Francis <dennisfrancis...@gmail.com>
AuthorDate: Thu Sep 2 14:33:55 2021 +0530
Commit:     Dennis Francis <dennis.fran...@collabora.com>
CommitDate: Tue Sep 7 08:19:22 2021 +0200

    [API CHANGE] oox: fix import of chart date categories
    
    Before this fix, date categories imported in oox's DataSourceContext were
    stored as formatted strings according to number format code in 
<c:formatCode>
    under the <c:cat> tree. As a result chart2 could not recognize them
    as dates. This causes problems like:
    
    * The axis that is linked to date categories cannot use the
      scaling/range-selection(min/max)/increments specs mentioned as axis
      properties. This results in distorted/unreadable chart renders w.r.t
      the date axis.
    
    * No re-formatting is attempted as per the number format provided for axis.
    
    This patch introduces a role qualifer argument to the XDataProvider
    interface method createDataSequenceByValueArray to support categories of
    date type via this method.
    
    When exporting to oox, write date categories and format code under
    <c:cat>
      <c:numRef>
        <c:numCache>
    
    This patch also fixes some discrepancies in date axis interval
    computation (auto mode) found by already existing unit tests.
    
    Conflicts:
            chart2/qa/extras/chart2export2.cxx
            chart2/source/inc/InternalDataProvider.hxx
            chart2/source/tools/InternalDataProvider.cxx
    
    Change-Id: Ibc53b0a56fdddba80ba452d5567ce98d80460ea7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121525
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit f547cf17a179ebd7de5c2b4dd2d00d0027a25429)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121723
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Dennis Francis <dennis.fran...@collabora.com>

diff --git a/chart2/qa/extras/chart2dump/chart2dump.cxx 
b/chart2/qa/extras/chart2dump/chart2dump.cxx
index 6ac2a0e21a49..89d47d77d884 100644
--- a/chart2/qa/extras/chart2dump/chart2dump.cxx
+++ b/chart2/qa/extras/chart2dump/chart2dump.cxx
@@ -615,6 +615,7 @@ DECLARE_DUMP_TEST(AxisLabelTest, Chart2DumpTest, false)
         "formated_axis_labels.odp",
         "percent_stacked_column_chart.odp",
         "tdf118150.xlsx",
+        "date-categories.pptx",
     };
 
     for (const OUString& sTestFile : aTestFiles)
diff --git a/chart2/qa/extras/chart2dump/data/date-categories.pptx 
b/chart2/qa/extras/chart2dump/data/date-categories.pptx
new file mode 100644
index 000000000000..b9e0c69f32b7
Binary files /dev/null and 
b/chart2/qa/extras/chart2dump/data/date-categories.pptx differ
diff --git 
a/chart2/qa/extras/chart2dump/reference/axislabeltest/date-categories.txt 
b/chart2/qa/extras/chart2dump/reference/axislabeltest/date-categories.txt
new file mode 100644
index 000000000000..a9274fd7838a
--- /dev/null
+++ b/chart2/qa/extras/chart2dump/reference/axislabeltest/date-categories.txt
@@ -0,0 +1,180 @@
+/// CID/D=0:CS=0:Axis=0,0
+// nAxisLabelsCount
+22
+// xLabel->getString()
+15/Jun/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+17/Jun/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+19/Jun/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+21/Jun/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+23/Jun/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+25/Jun/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+27/Jun/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+29/Jun/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+1/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+3/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+5/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+7/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+9/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+11/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+13/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+15/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+17/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+19/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+21/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+23/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+25/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+27/Jul/21
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+/// CID/D=0:CS=0:Axis=1,0
+// nAxisLabelsCount
+7
+// xLabel->getString()
+0
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+20
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+40
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+60
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+80
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+100
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
+// xLabel->getString()
+120
+// static_cast<sal_Int32>(aLabelFontColor)
+5855577
+// fLabelFontHeight
+9
diff --git a/chart2/qa/extras/chart2export.cxx 
b/chart2/qa/extras/chart2export.cxx
index 67d1b7dcb83c..d80e8fc6ae0d 100644
--- a/chart2/qa/extras/chart2export.cxx
+++ b/chart2/qa/extras/chart2export.cxx
@@ -186,6 +186,7 @@ public:
     void testTdf138181();
     void testCustomShapeText();
     void testTdf143942();
+    void testDateCategoriesPPTX();
 
     CPPUNIT_TEST_SUITE(Chart2ExportTest);
     CPPUNIT_TEST(testErrorBarXLSX);
@@ -334,6 +335,7 @@ public:
     CPPUNIT_TEST(testTdf138181);
     CPPUNIT_TEST(testCustomShapeText);
     CPPUNIT_TEST(testTdf143942);
+    CPPUNIT_TEST(testDateCategoriesPPTX);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -3140,6 +3142,44 @@ void Chart2ExportTest::testTdf143942()
     }
 }
 
+void Chart2ExportTest::testDateCategoriesPPTX()
+{
+    load("/chart2/qa/extras/data/pptx/", "bnc889755.pptx");
+    xmlDocUniquePtr pXmlDoc = parseExport("ppt/charts/chart", "Impress Office 
Open XML");
+    CPPUNIT_ASSERT(pXmlDoc);
+
+    constexpr size_t nCats = 16;
+    double aDates[nCats] = {
+        41183, 41214, 41244, 41275, 41306, 41334, 41365, 41395,
+        41426, 41456, 41487, 41518, 41548, 41579, 41609, 41640,
+    };
+
+    assertXPath(pXmlDoc, 
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat");
+    assertXPathContent(pXmlDoc,
+                       
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:numRef/"
+                       "c:numCache/c:formatCode",
+                       "mmm\\-yy");
+    assertXPath(
+        pXmlDoc,
+        
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:numRef/c:numCache/c:ptCount",
+        "val", OUString::number(nCats));
+
+    for (size_t i = 0; i < nCats; ++i)
+    {
+        assertXPath(
+            pXmlDoc,
+            
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:numRef/c:numCache/c:pt["
+                + OString::number(i + 1) + "]",
+            "idx", OUString::number(i));
+        assertXPathContent(
+            pXmlDoc,
+            
"/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[1]/c:cat/c:numRef/c:numCache/c:pt["
+                + OString::number(i + 1) + "]/c:v",
+            OUString::number(aDates[i]));
+    }
+}
+
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/chart2/qa/extras/chart2import.cxx 
b/chart2/qa/extras/chart2import.cxx
index 4b7d2fadb88b..5272e55aab93 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -29,7 +29,9 @@
 #include <com/sun/star/chart2/Symbol.hpp>
 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
 #include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart/XDateCategories.hpp>
 #include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/util/NumberFormatter.hpp>
 #include <iterator>
 #include <vcl/outdev.hxx>
 #include <vcl/svapp.hxx>
@@ -824,26 +826,20 @@ void Chart2ImportTest::testBnc889755()
     uno::Reference<chart2::XChartDocument> 
xChartDoc(getChartDocFromDrawImpress(0, 5), uno::UNO_QUERY_THROW);
     CPPUNIT_ASSERT(xChartDoc->hasInternalDataProvider());
 
-    uno::Reference< chart2::XInternalDataProvider > xDataProvider( 
xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW );
-    uno::Reference< chart::XChartDataArray > xChartDataArray(xDataProvider, 
uno::UNO_QUERY_THROW);
-    uno::Sequence< OUString > aRowLabels = 
xChartDataArray->getRowDescriptions();
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(16), aRowLabels.getLength());
-    CPPUNIT_ASSERT_EQUAL(OUString("Oct-12"), aRowLabels[0]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Nov-12"), aRowLabels[1]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Dec-12"), aRowLabels[2]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Jan-13"), aRowLabels[3]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Feb-13"), aRowLabels[4]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Mar-13"), aRowLabels[5]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Apr-13"), aRowLabels[6]);
-    CPPUNIT_ASSERT_EQUAL(OUString("May-13"), aRowLabels[7]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Jun-13"), aRowLabels[8]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Jul-13"), aRowLabels[9]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Aug-13"), aRowLabels[10]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Sep-13"), aRowLabels[11]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Oct-13"), aRowLabels[12]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Nov-13"), aRowLabels[13]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Dec-13"), aRowLabels[14]);
-    CPPUNIT_ASSERT_EQUAL(OUString("Jan-14"), aRowLabels[15]);
+    constexpr sal_Int32 nNumCategories = 16;
+    Sequence<OUString> aDateSeq = getFormattedDateCategories(xChartDoc);
+
+    CPPUNIT_ASSERT_EQUAL(nNumCategories, aDateSeq.getLength());
+
+    const OUString aExpectedDateCategories[nNumCategories] = {
+        "Oct-12", "Nov-12", "Dec-12", "Jan-13",
+        "Feb-13", "Mar-13", "Apr-13", "May-13",
+        "Jun-13", "Jul-13", "Aug-13", "Sep-13",
+        "Oct-13", "Nov-13", "Dec-13", "Jan-14",
+    };
+
+    for (size_t nIdx = 0; nIdx < nNumCategories; ++nIdx)
+        CPPUNIT_ASSERT_EQUAL(aExpectedDateCategories[nIdx], aDateSeq[nIdx]);
 
     //tdf#139940 - the title's gradient was lost and was filled with solid 
blue, instead of a "blue underline".
     uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, 
uno::UNO_QUERY_THROW);
@@ -1774,7 +1770,7 @@ void Chart2ImportTest::testInternalDataProvider() {
     const uno::Reference< chart2::data::XDataProvider >& rxDataProvider = 
xChartDoc->getDataProvider();
 
     // Parse 42 array
-    Reference<chart2::data::XDataSequence> xDataSeq = 
rxDataProvider->createDataSequenceByValueArray("values-y", "{42;42;42;42}");
+    Reference<chart2::data::XDataSequence> xDataSeq = 
rxDataProvider->createDataSequenceByValueArray("values-y", "{42;42;42;42}", "");
     Sequence<Any> xSequence = xDataSeq->getData();
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[0]);
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[1]);
@@ -1782,7 +1778,7 @@ void Chart2ImportTest::testInternalDataProvider() {
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[3]);
 
     // Parse empty first and last
-    xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", 
"{\"\";42;42;\"\"}");
+    xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", 
"{\"\";42;42;\"\"}", "");
     xSequence = xDataSeq->getData();
     CPPUNIT_ASSERT( std::isnan( *static_cast<const 
double*>(xSequence[0].getValue())));
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[1]);
@@ -1790,7 +1786,7 @@ void Chart2ImportTest::testInternalDataProvider() {
     CPPUNIT_ASSERT( std::isnan( *static_cast<const 
double*>(xSequence[3].getValue())));
 
     // Parse empty middle
-    xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", 
"{42;\"\";\"\";42}");
+    xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", 
"{42;\"\";\"\";42}", "");
     xSequence = xDataSeq->getData();
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[0]);
     CPPUNIT_ASSERT( std::isnan( *static_cast<const 
double*>(xSequence[1].getValue())) );
@@ -1798,7 +1794,7 @@ void Chart2ImportTest::testInternalDataProvider() {
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[3]);
 
     // Parse mixed types, numeric only role
-    xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", 
"{42;\"hello\";0;\"world\"}");
+    xDataSeq = rxDataProvider->createDataSequenceByValueArray("values-y", 
"{42;\"hello\";0;\"world\"}", "");
     xSequence = xDataSeq->getData();
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(42)), xSequence[0]);
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(0)),  xSequence[1]);
@@ -1806,7 +1802,7 @@ void Chart2ImportTest::testInternalDataProvider() {
     CPPUNIT_ASSERT_EQUAL(uno::Any(sal_Int32(0)),  xSequence[3]);
 
     // Parse mixed types, mixed role
-    xDataSeq = rxDataProvider->createDataSequenceByValueArray("categories", 
"{42;\"hello\";0;\"world\"}");
+    xDataSeq = rxDataProvider->createDataSequenceByValueArray("categories", 
"{42;\"hello\";0;\"world\"}", "");
     xSequence = xDataSeq->getData();
     CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Row 1 42")), xSequence[0]);
     CPPUNIT_ASSERT_EQUAL(uno::Any(OUString("Row 2 hello")), xSequence[1]);
diff --git a/chart2/qa/extras/charttest.hxx b/chart2/qa/extras/charttest.hxx
index 5257fb0acdc4..22908f19ad5b 100644
--- a/chart2/qa/extras/charttest.hxx
+++ b/chart2/qa/extras/charttest.hxx
@@ -32,6 +32,7 @@
 #include <rtl/math.hxx>
 #include <svx/charthelper.hxx>
 
+#include <com/sun/star/chart2/AxisType.hpp>
 #include <com/sun/star/chart2/XAnyDescriptionAccess.hpp>
 #include <com/sun/star/chart2/XChartDocument.hpp>
 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
@@ -43,12 +44,15 @@
 #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
 #include <com/sun/star/chart2/data/XDataSource.hpp>
 #include <com/sun/star/chart/XChartDataArray.hpp>
+#include <com/sun/star/chart2/XInternalDataProvider.hpp>
+#include <com/sun/star/chart/XDateCategories.hpp>
 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <com/sun/star/chart/XChartDocument.hpp>
 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
 #include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/NumberFormatter.hpp>
 
 #include <unonames.hxx>
 
@@ -82,6 +86,7 @@ public:
     uno::Reference<chart::XChartDocument> getChartDocFromDrawImpress( 
sal_Int32 nPage, sal_Int32 nShape );
 
     uno::Reference<chart::XChartDocument> getChartDocFromWriter( sal_Int32 
nShape );
+    Sequence< OUString > getFormattedDateCategories( const 
Reference<chart2::XChartDocument>& xChartDoc );
     awt::Size getPageSize( const Reference< chart2::XChartDocument > & 
xChartDoc );
     awt::Size getSize(css::uno::Reference<chart2::XDiagram> xDiagram, const 
awt::Size& rPageSize);
 
@@ -593,6 +598,38 @@ sal_Int16 getNumberFormatType( const 
Reference<chart2::XChartDocument>& xChartDo
     return nType;
 }
 
+Sequence< double > getDateCategories(const Reference<chart2::XChartDocument>& 
xChartDoc)
+{
+    CPPUNIT_ASSERT(xChartDoc->hasInternalDataProvider());
+    uno::Reference< chart2::XInternalDataProvider > xDataProvider( 
xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW );
+    uno::Reference< chart::XDateCategories > xDateCategories( xDataProvider, 
uno::UNO_QUERY_THROW );
+    CPPUNIT_ASSERT(xDateCategories.is());
+    return xDateCategories->getDateCategories();
+}
+
+Sequence< OUString > ChartTest::getFormattedDateCategories( const 
Reference<chart2::XChartDocument>& xChartDoc )
+{
+    Reference<util::XNumberFormatsSupplier> xNFS(xChartDoc, 
uno::UNO_QUERY_THROW);
+    Reference< util::XNumberFormatter > xNumFormatter(
+        
util::NumberFormatter::create(comphelper::getComponentContext(m_xSFactory)), 
uno::UNO_QUERY_THROW );
+    xNumFormatter->attachNumberFormatsSupplier(xNFS);
+
+    Reference<chart2::XAxis> xAxisX = getAxisFromDoc(xChartDoc, 0, 0, 0);
+    chart2::ScaleData aScaleData = xAxisX->getScaleData();
+    CPPUNIT_ASSERT_EQUAL(chart2::AxisType::DATE, aScaleData.AxisType);
+
+    sal_Int32 nNumFmt = getNumberFormatFromAxis(xAxisX);
+
+    Sequence<double> aDateSeq = getDateCategories(xChartDoc);
+    const sal_Int32 nNumCategories = aDateSeq.getLength();
+    Sequence<OUString> aFormattedDates(nNumCategories);
+
+    for (sal_Int32 nIdx = 0; nIdx < nNumCategories; ++nIdx)
+        aFormattedDates[nIdx] = xNumFormatter->convertNumberToString(nNumFmt, 
aDateSeq[nIdx]);
+
+    return aFormattedDates;
+}
+
 awt::Size ChartTest::getPageSize( const Reference< chart2::XChartDocument > & 
xChartDoc )
 {
     awt::Size aSize( 0, 0 );
diff --git a/chart2/source/inc/InternalDataProvider.hxx 
b/chart2/source/inc/InternalDataProvider.hxx
index 7e3291f2f582..e5bfb553dc34 100644
--- a/chart2/source/inc/InternalDataProvider.hxx
+++ b/chart2/source/inc/InternalDataProvider.hxx
@@ -112,7 +112,8 @@ public:
         const OUString& aRangeRepresentation ) override;
 
     virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
-        createDataSequenceByValueArray( const OUString& aRole, const OUString& 
aRangeRepresentation ) override;
+        createDataSequenceByValueArray( const OUString& aRole, const OUString& 
aRangeRepresentation,
+            const OUString& aRoleQualifier ) override;
 
     virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL 
getRangeSelection() override;
 
@@ -183,7 +184,8 @@ private:
         createDataSequenceAndAddToMap( const OUString & rRangeRepresentation );
 
     css::uno::Reference<css::chart2::data::XDataSequence>
-        createDataSequenceFromArray( const OUString& rArrayStr, const 
OUString& rRole );
+        createDataSequenceFromArray( const OUString& rArrayStr, const 
OUString& rRole,
+            const OUString& rRoleQualifier );
 
     void deleteMapReferences( const OUString & rRangeRepresentation );
 
diff --git a/chart2/source/tools/InternalDataProvider.cxx 
b/chart2/source/tools/InternalDataProvider.cxx
index 415f08ac3ea9..d6b02814ab78 100644
--- a/chart2/source/tools/InternalDataProvider.cxx
+++ b/chart2/source/tools/InternalDataProvider.cxx
@@ -486,7 +486,7 @@ void InternalDataProvider::decreaseMapReferences(
 Reference< chart2::data::XDataSequence > 
InternalDataProvider::createDataSequenceAndAddToMap(
     const OUString & rRangeRepresentation )
 {
-    Reference<chart2::data::XDataSequence> xSeq = 
createDataSequenceFromArray(rRangeRepresentation, OUString());
+    Reference<chart2::data::XDataSequence> xSeq = 
createDataSequenceFromArray(rRangeRepresentation, OUString(), OUString());
     if (xSeq.is())
         return xSeq;
 
@@ -496,7 +496,7 @@ Reference< chart2::data::XDataSequence > 
InternalDataProvider::createDataSequenc
 }
 
 uno::Reference<chart2::data::XDataSequence>
-InternalDataProvider::createDataSequenceFromArray( const OUString& rArrayStr, 
const OUString& rRole )
+InternalDataProvider::createDataSequenceFromArray( const OUString& rArrayStr, 
const OUString& rRole, const OUString& rRoleQualifier )
 {
     if (rArrayStr.indexOf('{') != 0 || rArrayStr[rArrayStr.getLength()-1] != 
'}')
     {
@@ -623,9 +623,19 @@ InternalDataProvider::createDataSequenceFromArray( const 
OUString& rArrayStr, co
     {
         // Category labels.
 
+        // Store date categories as numbers.
+        bool bStoreNumeric = rRoleQualifier == "date";
+        double fValue;
         for (size_t i = 0; i < aRawElems.size(); ++i)
         {
-            std::vector<uno::Any> aLabels(1, uno::Any(aRawElems[i]));
+            if (bStoreNumeric)
+            {
+                bool bGetDouble = bAllNumeric && !aRawElems[i].isEmpty();
+                fValue = bGetDouble ? aRawElems[i].toDouble() :
+                    std::numeric_limits<double>::quiet_NaN();
+            }
+            std::vector<uno::Any> aLabels(1,
+                bStoreNumeric ? uno::Any(fValue) : uno::Any(aRawElems[i]));
             m_aInternalData.setComplexRowLabel(i, aLabels);
         }
 
@@ -834,9 +844,9 @@ Reference< chart2::data::XDataSequence > SAL_CALL 
InternalDataProvider::createDa
 
 Reference<chart2::data::XDataSequence> SAL_CALL
 InternalDataProvider::createDataSequenceByValueArray(
-    const OUString& aRole, const OUString& aRangeRepresentation )
+    const OUString& aRole, const OUString& aRangeRepresentation, const 
OUString& aRoleQualifier )
 {
-    return createDataSequenceFromArray(aRangeRepresentation, aRole);
+    return createDataSequenceFromArray(aRangeRepresentation, aRole, 
aRoleQualifier);
 }
 
 Reference< sheet::XRangeSelection > SAL_CALL 
InternalDataProvider::getRangeSelection()
diff --git a/chart2/source/view/axes/ScaleAutomatism.cxx 
b/chart2/source/view/axes/ScaleAutomatism.cxx
index 7557f9b3d95b..8b7c94b6f60e 100644
--- a/chart2/source/view/axes/ScaleAutomatism.cxx
+++ b/chart2/source/view/axes/ScaleAutomatism.cxx
@@ -656,7 +656,7 @@ void 
ScaleAutomatism::calculateExplicitIncrementAndScaleForDateTimeAxis(
             nDaysPerInterval = 1.0;
         }
 
-        nNumer = static_cast<sal_Int32>( rtl::math::approxCeil( 
nIntervalDays/nDaysPerInterval ) );
+        nNumer = static_cast<sal_Int32>( rtl::math::approxFloor( 
nIntervalDays/nDaysPerInterval ) );
         if(nNumer<=0)
             nNumer=1;
         if( rExplicitIncrement.MajorTimeInterval.TimeUnit == DAY )
@@ -667,7 +667,7 @@ void 
ScaleAutomatism::calculateExplicitIncrementAndScaleForDateTimeAxis(
             {
                 rExplicitIncrement.MajorTimeInterval.TimeUnit = MONTH;
                 nDaysPerInterval = 31.0;
-                nNumer = static_cast<sal_Int32>( rtl::math::approxCeil( 
nIntervalDays/nDaysPerInterval ) );
+                nNumer = static_cast<sal_Int32>( rtl::math::approxFloor( 
nIntervalDays/nDaysPerInterval ) );
                 if(nNumer<=0)
                     nNumer=1;
             }
diff --git a/chart2/source/view/axes/VCoordinateSystem.cxx 
b/chart2/source/view/axes/VCoordinateSystem.cxx
index 1c900b392233..b8d916c375d9 100644
--- a/chart2/source/view/axes/VCoordinateSystem.cxx
+++ b/chart2/source/view/axes/VCoordinateSystem.cxx
@@ -342,7 +342,8 @@ void VCoordinateSystem::updateScalesAndIncrementsOnAxes()
 
 void VCoordinateSystem::prepareAutomaticAxisScaling( ScaleAutomatism& 
rScaleAutomatism, sal_Int32 nDimIndex, sal_Int32 nAxisIndex )
 {
-    if( rScaleAutomatism.getScale().AxisType==AxisType::DATE && nDimIndex==0 )
+    bool bDateAxisX = (rScaleAutomatism.getScale().AxisType == AxisType::DATE) 
&& (nDimIndex == 0);
+    if( bDateAxisX )
     {
         // This is a date X dimension.  Determine proper time resolution.
         sal_Int32 nTimeResolution = css::chart::TimeUnit::MONTH;
@@ -387,6 +388,9 @@ void VCoordinateSystem::prepareAutomaticAxisScaling( 
ScaleAutomatism& rScaleAuto
         m_aMergedMinMaxSupplier.isExpandWideValuesToZero( nDimIndex ),
         m_aMergedMinMaxSupplier.isExpandNarrowValuesTowardZero( nDimIndex ) );
 
+    if (bDateAxisX)
+        return;
+
     VAxisBase* pVAxis = getVAxis(nDimIndex, nAxisIndex);
     if( pVAxis )
         rScaleAutomatism.setMaximumAutoMainIncrementCount( 
pVAxis->estimateMaximumAutoMainIncrementCount() );
diff --git a/chart2/source/view/charttypes/AreaChart.cxx 
b/chart2/source/view/charttypes/AreaChart.cxx
index a658a26d04a6..09e6bb504b7e 100644
--- a/chart2/source/view/charttypes/AreaChart.cxx
+++ b/chart2/source/view/charttypes/AreaChart.cxx
@@ -694,6 +694,8 @@ void AreaChart::createShapes()
                 uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = 
getSeriesGroupShapeFrontChild(pSeries.get(), m_xSeriesTarget);
 
                 sal_Int32 nAttachedAxisIndex = pSeries->getAttachedAxisIndex();
+                double fXMin, fXMax;
+                pSeries->getMinMaxXValue(fXMin, fXMax);
                 PlottingPositionHelper& rPosHelper = 
getPlottingPositionHelper(nAttachedAxisIndex);
                 m_pPosHelper = &rPosHelper;
 
@@ -714,7 +716,7 @@ void AreaChart::createShapes()
                     double fLogicX = pSeries->getXValue(nIndex);
                     if (bDateCategory)
                     {
-                        if (std::isnan(fLogicX))
+                        if (std::isnan(fLogicX) || (fLogicX < fXMin || fLogicX 
> fXMax))
                             continue;
 
                         fLogicX = DateHelper::RasterizeDateValue( fLogicX, 
m_aNullDate, m_nTimeResolution );
diff --git a/dbaccess/source/core/inc/DatabaseDataProvider.hxx 
b/dbaccess/source/core/inc/DatabaseDataProvider.hxx
index 5df139157d78..955e2e107b6e 100644
--- a/dbaccess/source/core/inc/DatabaseDataProvider.hxx
+++ b/dbaccess/source/core/inc/DatabaseDataProvider.hxx
@@ -73,7 +73,7 @@ private:
 
     virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
         createDataSequenceByValueArray(
-            const OUString& aRole, const OUString & aRangeRepresentation) 
override;
+            const OUString& aRole, const OUString & aRangeRepresentation, 
const OUString& aRoleQualifier) override;
 
     virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL 
getRangeSelection() override;
 
diff --git a/dbaccess/source/core/misc/DatabaseDataProvider.cxx 
b/dbaccess/source/core/misc/DatabaseDataProvider.cxx
index b6366e4482fb..ac98e0c4c81b 100644
--- a/dbaccess/source/core/misc/DatabaseDataProvider.cxx
+++ b/dbaccess/source/core/misc/DatabaseDataProvider.cxx
@@ -276,7 +276,7 @@ uno::Reference< chart2::data::XDataSequence > SAL_CALL 
DatabaseDataProvider::cre
 
 uno::Reference<chart2::data::XDataSequence>
 SAL_CALL DatabaseDataProvider::createDataSequenceByValueArray(
-    const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/ )
+    const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/, const 
OUString& /*aRoleQualifier*/ )
 {
     return uno::Reference<chart2::data::XDataSequence>();
 }
diff --git a/include/oox/drawingml/chart/chartconverter.hxx 
b/include/oox/drawingml/chart/chartconverter.hxx
index c293c48215bb..fcf3b2fee3fa 100644
--- a/include/oox/drawingml/chart/chartconverter.hxx
+++ b/include/oox/drawingml/chart/chartconverter.hxx
@@ -84,7 +84,8 @@ public:
     virtual css::uno::Reference<css::chart2::data::XDataSequence>
         createDataSequence(
             const css::uno::Reference<css::chart2::data::XDataProvider>& 
rxDataProvider,
-            const DataSequenceModel& rDataSeq, const OUString& rRole );
+            const DataSequenceModel& rDataSeq, const OUString& rRole,
+            const OUString& aRoleQualifier );
 
 private:
                         ChartConverter( const ChartConverter& ) = delete;
diff --git a/include/oox/drawingml/chart/datasourcemodel.hxx 
b/include/oox/drawingml/chart/datasourcemodel.hxx
index dc8d253a7d11..49b8dcd90717 100644
--- a/include/oox/drawingml/chart/datasourcemodel.hxx
+++ b/include/oox/drawingml/chart/datasourcemodel.hxx
@@ -27,6 +27,8 @@
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
 
+enum class SvNumFormatType : sal_Int16;
+
 namespace oox::drawingml::chart {
 
 
@@ -39,6 +41,7 @@ struct DataSequenceModel
     OUString     maFormatCode;       /// Number format for double values.
     sal_Int32           mnPointCount;       /// Number of points in this 
series source.
     sal_Int32           mnLevelCount;       /// Number of category levels.
+    SvNumFormatType     meFormatType;       /// Type of number format in 
maFormatCode.
 
     explicit            DataSequenceModel();
                         ~DataSequenceModel();
diff --git a/include/oox/export/chartexport.hxx 
b/include/oox/export/chartexport.hxx
index 3771809c9d87..4021c6f02ccd 100644
--- a/include/oox/export/chartexport.hxx
+++ b/include/oox/export/chartexport.hxx
@@ -138,6 +138,7 @@ private:
     bool                mbIs3DChart;
     bool                mbStacked;
     bool                mbPercent;
+    bool                mbHasDateCategories;
 
     std::set<sal_Int32> maExportedAxis;
 
diff --git a/offapi/com/sun/star/chart2/data/XDataProvider.idl 
b/offapi/com/sun/star/chart2/data/XDataProvider.idl
index 6ab3fd4aaadd..e0f450a1a501 100644
--- a/offapi/com/sun/star/chart2/data/XDataProvider.idl
+++ b/offapi/com/sun/star/chart2/data/XDataProvider.idl
@@ -126,7 +126,28 @@ interface XDataProvider  : 
::com::sun::star::uno::XInterface
         [in] string aRangeRepresentation )
         raises( com::sun::star::lang::IllegalArgumentException );
 
-    XDataSequence createDataSequenceByValueArray( [in] string aRole, [in] 
string aValueArray )
+    /** Creates a single data sequence from the string value array 
representation
+
+        @param aRole
+            The role of the sequence inside a data series. This may be any
+            string. However some strings are predefined and should always
+            be used in the same way.
+
+        @param aValueArray
+            is a string that contains the value representation of the
+            sequence to be created.
+
+        @param aRoleQualifier
+            is a string that describes the role of the sequence.
+            This may be any string. However some strings are predefined
+            and should always be used in the same way.
+
+        @throws com::sun::star::lang::IllegalArgumentException
+            if the given value array does not contain a valid value array
+            representation.
+     */
+    XDataSequence createDataSequenceByValueArray( [in] string aRole, [in] 
string aValueArray,
+        [in] string aRoleQualifier )
         raises( com::sun::star::lang::IllegalArgumentException );
 
     /** Returns a component that is able to change a given range
diff --git a/oox/source/drawingml/chart/chartconverter.cxx 
b/oox/source/drawingml/chart/chartconverter.cxx
index a864aac47e47..af49c561ae51 100644
--- a/oox/source/drawingml/chart/chartconverter.cxx
+++ b/oox/source/drawingml/chart/chartconverter.cxx
@@ -116,7 +116,7 @@ void ChartConverter::createDataProvider( const Reference< 
XChartDocument >& rxCh
 
 Reference< XDataSequence > ChartConverter::createDataSequence(
     const Reference< XDataProvider >& rxDataProvider, const DataSequenceModel& 
rDataSeq,
-    const OUString& rRole )
+    const OUString& rRole, const OUString& rRoleQualifier )
 {
     Reference< XDataSequence > xDataSeq;
     if( rxDataProvider.is() )
@@ -137,7 +137,7 @@ Reference< XDataSequence > 
ChartConverter::createDataSequence(
                 if (!aRangeRep.isEmpty())
                 {
                     // create or add a new level to the data sequence
-                    xDataSeq = 
rxDataProvider->createDataSequenceByValueArray(rRole, aRangeRep);
+                    xDataSeq = 
rxDataProvider->createDataSequenceByValueArray(rRole, aRangeRep, 
rRoleQualifier);
                     if (i == 0)
                         return xDataSeq;
                 }
diff --git a/oox/source/drawingml/chart/datasourcecontext.cxx 
b/oox/source/drawingml/chart/datasourcecontext.cxx
index 15ca02975137..8ee52d89d0d9 100644
--- a/oox/source/drawingml/chart/datasourcecontext.cxx
+++ b/oox/source/drawingml/chart/datasourcecontext.cxx
@@ -98,7 +98,7 @@ void DoubleSequenceContext::onCharacters( const OUString& 
rChars )
             if( mnPtIndex >= 0 )
             {
                 /* Import categories as String even though it could
-                 * be values.
+                 * be values except when the format code indicates that they 
are dates.
                  * n#810508: xVal needs to be imported as double
                  * TODO: NumberFormat conversion, remove the check then.
                  */
@@ -117,6 +117,8 @@ void DoubleSequenceContext::onCharacters( const OUString& 
rChars )
                             SvNumFormatType nType;
                             pNumFrmt->PutEntry( aFormatCode, nCheckPos, nType, 
nKey );
                             bNoKey = (nCheckPos != 0);
+                            if (!bNoKey)
+                                mrModel.meFormatType = nType;
                         }
                         if( bNoKey )
                         {
@@ -125,13 +127,18 @@ void DoubleSequenceContext::onCharacters( const OUString& 
rChars )
                         else
                         {
                             double fValue = rChars.toDouble();
-                            const ::Color* pColor = nullptr;
-                            OUString aFormattedValue;
-                            // tdf#91250: use UNLIMITED_PRECISION in case of 
GENERAL Number Format of category axis labels
-                            if( pNumFrmt->GetStandardPrec() != 
SvNumberFormatter::UNLIMITED_PRECISION )
-                                
pNumFrmt->ChangeStandardPrec(SvNumberFormatter::UNLIMITED_PRECISION);
-                            pNumFrmt->GetOutputString( fValue, nKey, 
aFormattedValue, &pColor );
-                            mrModel.maData[ mnPtIndex ] <<= aFormattedValue;
+                            if (mrModel.meFormatType == SvNumFormatType::DATE)
+                                mrModel.maData[ mnPtIndex ] <<= fValue;
+                            else
+                            {
+                                const ::Color* pColor = nullptr;
+                                OUString aFormattedValue;
+                                // tdf#91250: use UNLIMITED_PRECISION in case 
of GENERAL Number Format of category axis labels
+                                if( pNumFrmt->GetStandardPrec() != 
SvNumberFormatter::UNLIMITED_PRECISION )
+                                    
pNumFrmt->ChangeStandardPrec(SvNumberFormatter::UNLIMITED_PRECISION);
+                                pNumFrmt->GetOutputString( fValue, nKey, 
aFormattedValue, &pColor );
+                                mrModel.maData[ mnPtIndex ] <<= 
aFormattedValue;
+                            }
                         }
                     }
                     else
diff --git a/oox/source/drawingml/chart/datasourceconverter.cxx 
b/oox/source/drawingml/chart/datasourceconverter.cxx
index 72399426538d..92cacb4286bf 100644
--- a/oox/source/drawingml/chart/datasourceconverter.cxx
+++ b/oox/source/drawingml/chart/datasourceconverter.cxx
@@ -23,6 +23,7 @@
 #include <oox/drawingml/chart/chartconverter.hxx>
 #include <oox/drawingml/chart/datasourcemodel.hxx>
 #include <oox/token/properties.hxx>
+#include <svl/zforlist.hxx>
 
 namespace oox::drawingml::chart {
 
@@ -69,7 +70,10 @@ Reference< XDataSequence > 
DataSequenceConverter::createDataSequence( const OUSt
             mrModel.maData.insert(std::make_pair<sal_Int32, Any>(0, 
Any(aTitle.makeStringAndClear())));
         }
     }
-    xDataSeq = 
getChartConverter().createDataSequence(getChartDocument()->getDataProvider(), 
mrModel, rRole);
+
+    bool bDateCategories = (mrModel.meFormatType == SvNumFormatType::DATE) && 
(rRole == "categories");
+    xDataSeq = 
getChartConverter().createDataSequence(getChartDocument()->getDataProvider(), 
mrModel,
+        rRole, bDateCategories ? OUString("date") : OUString(""));
 
     // set sequence role
     PropertySet aSeqProp( xDataSeq );
diff --git a/oox/source/drawingml/chart/datasourcemodel.cxx 
b/oox/source/drawingml/chart/datasourcemodel.cxx
index e83b6b3558a5..51514437d33d 100644
--- a/oox/source/drawingml/chart/datasourcemodel.cxx
+++ b/oox/source/drawingml/chart/datasourcemodel.cxx
@@ -18,12 +18,14 @@
  */
 
 #include <oox/drawingml/chart/datasourcemodel.hxx>
+#include <svl/zforlist.hxx>
 
 namespace oox::drawingml::chart {
 
 DataSequenceModel::DataSequenceModel() :
     mnPointCount( -1 ),
-    mnLevelCount( 1 )
+    mnLevelCount( 1 ),
+    meFormatType( SvNumFormatType::UNDEFINED )
 {
 }
 
diff --git a/oox/source/export/chartexport.cxx 
b/oox/source/export/chartexport.cxx
index 83f7ad8d5d93..9b6831e8e9a3 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -156,8 +156,9 @@ private:
 
 }
 
-static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( 
const Reference< chart2::XDiagram > & xDiagram )
+static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( 
const Reference< chart2::XDiagram > & xDiagram, bool& bHasDateCategories )
 {
+    bHasDateCategories = false;
     Reference< chart2::data::XLabeledDataSequence >  xResult;
     try
     {
@@ -180,6 +181,7 @@ static Reference< chart2::data::XLabeledDataSequence > 
lcl_getCategories( const
                         chart2::ScaleData aScaleData = xAxis->getScaleData();
                         if( aScaleData.Categories.is())
                         {
+                            bHasDateCategories = aScaleData.AxisType == 
chart2::AxisType::DATE;
                             xResult.set( aScaleData.Categories );
                             break;
                         }
@@ -218,7 +220,8 @@ static bool lcl_hasCategoryLabels( const Reference< 
chart2::XChartDocument >& xC
 {
     //categories are always the first sequence
     Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
-    Reference< chart2::data::XLabeledDataSequence > xCategories( 
lcl_getCategories( xDiagram ) );
+    bool bDateCategories;
+    Reference< chart2::data::XLabeledDataSequence > xCategories( 
lcl_getCategories( xDiagram, bDateCategories ) );
     return xCategories.is();
 }
 
@@ -2717,7 +2720,26 @@ void ChartExport::exportSeriesCategory( const Reference< 
chart2::data::XDataSequ
     else
     {
         // export single category axis labels
-        pFS->startElement(FSNS(XML_c, XML_strRef));
+        bool bWriteDateCategories = mbHasDateCategories && (nValueType == 
XML_cat);
+        OUString aNumberFormatString;
+        if (bWriteDateCategories)
+        {
+            Reference< css::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, 
uno::UNO_QUERY );
+            if( xAxisXSupp.is())
+            {
+                Reference< XPropertySet > xAxisProp = xAxisXSupp->getXAxis();
+                if (GetProperty(xAxisProp, "NumberFormat"))
+                {
+                    sal_Int32 nKey = 0;
+                    mAny >>= nKey;
+                    aNumberFormatString = getNumberFormatCode(nKey);
+                }
+            }
+            if (aNumberFormatString.isEmpty())
+                bWriteDateCategories = false;
+        }
+
+        pFS->startElement(FSNS(XML_c, bWriteDateCategories ? XML_numRef : 
XML_strRef));
 
         pFS->startElement(FSNS(XML_c, XML_f));
         pFS->writeEscaped(aCellRange);
@@ -2726,7 +2748,14 @@ void ChartExport::exportSeriesCategory( const Reference< 
chart2::data::XDataSequ
         ::std::vector< OUString > aCategories;
         lcl_fillCategoriesIntoStringVector(xValueSeq, aCategories);
         sal_Int32 ptCount = aCategories.size();
-        pFS->startElement(FSNS(XML_c, XML_strCache));
+        pFS->startElement(FSNS(XML_c, bWriteDateCategories ? XML_numCache : 
XML_strCache));
+        if (bWriteDateCategories)
+        {
+            pFS->startElement(FSNS(XML_c, XML_formatCode));
+            pFS->writeEscaped(aNumberFormatString);
+            pFS->endElement(FSNS(XML_c, XML_formatCode));
+        }
+
         pFS->singleElement(FSNS(XML_c, XML_ptCount), XML_val, 
OString::number(ptCount));
         for (sal_Int32 i = 0; i < ptCount; i++)
         {
@@ -2737,8 +2766,8 @@ void ChartExport::exportSeriesCategory( const Reference< 
chart2::data::XDataSequ
             pFS->endElement(FSNS(XML_c, XML_pt));
         }
 
-        pFS->endElement(FSNS(XML_c, XML_strCache));
-        pFS->endElement(FSNS(XML_c, XML_strRef));
+        pFS->endElement(FSNS(XML_c, bWriteDateCategories ? XML_numCache : 
XML_strCache));
+        pFS->endElement(FSNS(XML_c, bWriteDateCategories ? XML_numRef : 
XML_strRef));
     }
 
     pFS->endElement( FSNS( XML_c, nValueType ) );
@@ -2881,7 +2910,7 @@ void ChartExport::InitPlotArea( )
 
     if( mbHasCategoryLabels && mxNewDiagram.is())
     {
-        Reference< chart2::data::XLabeledDataSequence > xCategories( 
lcl_getCategories( mxNewDiagram ) );
+        Reference< chart2::data::XLabeledDataSequence > xCategories( 
lcl_getCategories( mxNewDiagram, mbHasDateCategories ) );
         if( xCategories.is() )
         {
             mxCategoriesValues.set( xCategories->getValues() );
diff --git a/sc/inc/PivotTableDataProvider.hxx 
b/sc/inc/PivotTableDataProvider.hxx
index 3dadfa94cd8e..8e8189736f2f 100644
--- a/sc/inc/PivotTableDataProvider.hxx
+++ b/sc/inc/PivotTableDataProvider.hxx
@@ -69,7 +69,8 @@ public:
             createDataSequenceByRangeRepresentation(const OUString& 
aRangeRepresentation) override;
 
     virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
-        createDataSequenceByValueArray(const OUString& aRole, const OUString& 
aRangeRepresentation) override;
+        createDataSequenceByValueArray(const OUString& aRole, const OUString& 
aRangeRepresentation,
+            const OUString& aRoleQualifier) override;
 
     virtual css::uno::Reference<css::sheet::XRangeSelection> SAL_CALL 
getRangeSelection() override;
 
diff --git a/sc/inc/chart2uno.hxx b/sc/inc/chart2uno.hxx
index 5f63433feef3..98f046e2e56f 100644
--- a/sc/inc/chart2uno.hxx
+++ b/sc/inc/chart2uno.hxx
@@ -88,7 +88,8 @@ public:
             const OUString& aRangeRepresentation ) override;
 
     virtual css::uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
-        createDataSequenceByValueArray( const OUString& aRole, const OUString& 
aRangeRepresentation ) override;
+        createDataSequenceByValueArray( const OUString& aRole, const OUString& 
aRangeRepresentation,
+            const OUString& aRoleQualifier ) override;
 
     virtual css::uno::Reference< css::sheet::XRangeSelection > SAL_CALL 
getRangeSelection() override;
 
diff --git a/sc/source/filter/inc/excelchartconverter.hxx 
b/sc/source/filter/inc/excelchartconverter.hxx
index 89af4d9988b2..df7e6ac29213 100644
--- a/sc/source/filter/inc/excelchartconverter.hxx
+++ b/sc/source/filter/inc/excelchartconverter.hxx
@@ -39,7 +39,8 @@ public:
     virtual css::uno::Reference<css::chart2::data::XDataSequence>
         createDataSequence(
             const css::uno::Reference<css::chart2::data::XDataProvider>& 
rxDataProvider,
-            const oox::drawingml::chart::DataSequenceModel& rDataSeq, const 
OUString& rRole ) override;
+            const oox::drawingml::chart::DataSequenceModel& rDataSeq, const 
OUString& rRole,
+            const OUString& aRoleQualifier ) override;
 };
 
 } // namespace oox::xls
diff --git a/sc/source/filter/oox/excelchartconverter.cxx 
b/sc/source/filter/oox/excelchartconverter.cxx
index 50695b1fb8f9..bc9a0bd030bf 100644
--- a/sc/source/filter/oox/excelchartconverter.cxx
+++ b/sc/source/filter/oox/excelchartconverter.cxx
@@ -64,7 +64,7 @@ void ExcelChartConverter::createDataProvider( const 
Reference< XChartDocument >&
 
 Reference< XDataSequence > ExcelChartConverter::createDataSequence(
     const Reference< XDataProvider >& rxDataProvider, const DataSequenceModel& 
rDataSeq,
-    const OUString& /*rRole*/ )
+    const OUString& /*rRole*/, const OUString& /*aRoleQualifier*/ )
 {
     Reference< XDataSequence > xDataSeq;
     if (!rxDataProvider.is())
diff --git a/sc/source/ui/unoobj/PivotTableDataProvider.cxx 
b/sc/source/ui/unoobj/PivotTableDataProvider.cxx
index 8288be2e530b..2cd61fd3b843 100644
--- a/sc/source/ui/unoobj/PivotTableDataProvider.cxx
+++ b/sc/source/ui/unoobj/PivotTableDataProvider.cxx
@@ -712,7 +712,8 @@ uno::Reference<chart2::data::XDataSequence> SAL_CALL
 
 uno::Reference<chart2::data::XDataSequence> SAL_CALL
     PivotTableDataProvider::createDataSequenceByValueArray(const OUString& 
/*aRole*/,
-                                                           const OUString& 
/*aRangeRepresentation*/)
+                                                           const OUString& 
/*aRangeRepresentation*/,
+                                                           const OUString& 
/*aRoleQualifier*/)
 {
     return uno::Reference<chart2::data::XDataSequence>();
 }
diff --git a/sc/source/ui/unoobj/chart2uno.cxx 
b/sc/source/ui/unoobj/chart2uno.cxx
index 004729176c2e..c8bc1fc77996 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -2008,7 +2008,8 @@ uno::Reference< chart2::data::XDataSequence > SAL_CALL
 
 uno::Reference<chart2::data::XDataSequence> SAL_CALL
 ScChart2DataProvider::createDataSequenceByValueArray(
-    const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/ )
+    const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/,
+    const OUString& /*aRoleQualifier*/ )
 {
     return uno::Reference<chart2::data::XDataSequence>();
 }
diff --git a/sw/inc/unochart.hxx b/sw/inc/unochart.hxx
index 7147f8a036eb..f17f832600b0 100644
--- a/sw/inc/unochart.hxx
+++ b/sw/inc/unochart.hxx
@@ -155,7 +155,7 @@ public:
 
     virtual css::uno::Reference<css::chart2::data::XDataSequence>
         SAL_CALL createDataSequenceByValueArray(
-            const OUString& aRole, const OUString& aRangeRepresentation ) 
override;
+            const OUString& aRole, const OUString& aRangeRepresentation, const 
OUString& aRoleQualifier ) override;
 
     // XRangeXMLConversion
     virtual OUString SAL_CALL convertRangeToXML( const OUString& 
aRangeRepresentation ) override;
diff --git a/sw/source/core/unocore/unochart.cxx 
b/sw/source/core/unocore/unochart.cxx
index 8bc55cc0487e..bfa6b7802238 100644
--- a/sw/source/core/unocore/unochart.cxx
+++ b/sw/source/core/unocore/unochart.cxx
@@ -1350,7 +1350,8 @@ uno::Reference< sheet::XRangeSelection > SAL_CALL 
SwChartDataProvider::getRangeS
 
 uno::Reference<css::chart2::data::XDataSequence> SAL_CALL
     SwChartDataProvider::createDataSequenceByValueArray(
-        const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/ )
+        const OUString& /*aRole*/, const OUString& /*aRangeRepresentation*/,
+        const OUString& /*aRoleQualifier*/ )
 {
     return uno::Reference<css::chart2::data::XDataSequence>();
 }

Reply via email to