chart2/qa/extras/chart2export2.cxx | 11 dev/null |binary include/oox/drawingml/chart/datasourcemodel.hxx | 18 include/oox/export/chartexport.hxx | 13 include/test/xmltesttools.hxx | 23 oox/inc/drawingml/chart/chartspacemodel.hxx | 2 oox/inc/drawingml/chart/datasourcecontext.hxx | 17 oox/inc/drawingml/chart/plotareaconverter.hxx | 5 oox/inc/drawingml/chart/seriesconverter.hxx | 3 oox/inc/drawingml/chart/seriesmodel.hxx | 19 oox/inc/drawingml/chart/typegroupconverter.hxx | 8 oox/source/drawingml/chart/chartconverter.cxx | 1 oox/source/drawingml/chart/chartspaceconverter.cxx | 3 oox/source/drawingml/chart/chartspacefragment.cxx | 4 oox/source/drawingml/chart/datasourcecontext.cxx | 110 --- oox/source/drawingml/chart/plotareaconverter.cxx | 18 oox/source/drawingml/chart/seriescontext.cxx | 40 - oox/source/drawingml/chart/seriesconverter.cxx | 11 oox/source/drawingml/chart/seriesmodel.cxx | 1 oox/source/drawingml/chart/typegroupconverter.cxx | 30 oox/source/export/chartexport.cxx | 690 ++++++--------------- test/source/xmltesttools.cxx | 19 22 files changed, 266 insertions(+), 780 deletions(-)
New commits: commit 1ad9bb2c7f13f55385a77b471b223cc97f30d60d Author: Kurt Nordback <[email protected]> AuthorDate: Wed Jan 21 11:35:48 2026 -0700 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Mon Jan 26 08:18:58 2026 +0100 Revert "tdf#165742 Step 4.7: Add support for internal data" This reverts commit b685463a1a586ffbd8a190657603750a990a8994. Change-Id: I74388898011ad69a60186920e3bc18cb5955bfe4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197897 Reviewed-by: Tomaž Vajngerl <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/chart2/qa/extras/chart2export2.cxx b/chart2/qa/extras/chart2export2.cxx index d4881a353a59..000dfcf90038 100644 --- a/chart2/qa/extras/chart2export2.cxx +++ b/chart2/qa/extras/chart2export2.cxx @@ -171,17 +171,6 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest2, testChartexTitleXLSX) u"Funnel chart!"); } -CPPUNIT_TEST_FIXTURE(Chart2ExportTest2, testChartexPPTX) -{ - loadFromFile(u"pptx/funnel-pp1.pptx"); - save(u"Impress Office Open XML"_ustr); - xmlDocUniquePtr pXmlDoc = parseExport(u"ppt/charts/chartEx1.xml"_ustr); - CPPUNIT_ASSERT(pXmlDoc); - - assertXPath(pXmlDoc, "/cx:chartSpace/cx:chart/cx:plotArea/cx:plotAreaRegion/cx:series", 3, 0, - "layoutId", u"funnel"); -} - CPPUNIT_TEST_FIXTURE(Chart2ExportTest2, testAxisTitleRotationXLSX) { loadFromFile(u"xlsx/axis_title_rotation.xlsx"); diff --git a/chart2/qa/extras/data/pptx/funnel-pp1.pptx b/chart2/qa/extras/data/pptx/funnel-pp1.pptx deleted file mode 100644 index df34aa1618d0..000000000000 Binary files a/chart2/qa/extras/data/pptx/funnel-pp1.pptx and /dev/null differ diff --git a/include/oox/drawingml/chart/datasourcemodel.hxx b/include/oox/drawingml/chart/datasourcemodel.hxx index 7cc52208e6a0..49b8dcd90717 100644 --- a/include/oox/drawingml/chart/datasourcemodel.hxx +++ b/include/oox/drawingml/chart/datasourcemodel.hxx @@ -58,24 +58,6 @@ struct DataSourceModel ~DataSourceModel(); }; -enum class DataSourceType: sal_Int32; - -// Data source for chartex -struct DataSourceCxModel -{ - // Same as definition in SeriesModel - typedef ModelMap< DataSourceType, DataSourceModel > DataSourceMap; - typedef ModelMap<sal_Int32, DataSourceMap> DataMap; - - // Chartex data can have three levels of lists/maps: - // 1. Multiple data series, each with a <cx:data> tag and indexed by id. - // 2. Within a series, multiple sources ("val", "cat", etc.) - // 3. Within a source, multiple points, with corresponding index. - DataMap maSourceMap; /// Data for chartex. - - explicit DataSourceCxModel() = default; -}; - } // namespace oox::drawingml::chart diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx index 5900ce9496e4..4cdc9f748493 100644 --- a/include/oox/export/chartexport.hxx +++ b/include/oox/export/chartexport.hxx @@ -177,8 +177,9 @@ private: void exportChart( const css::uno::Reference< css::chart::XChartDocument >& rChartDoc, bool bIsChartex); - void exportData_chartex( const css::uno::Reference< - css::chart::XChartDocument >& rChartDoc); + void exportData( const css::uno::Reference< + css::chart::XChartDocument >& rChartDoc, + bool bIsChartex); void exportExternalData( const css::uno::Reference< css::chart::XChartDocument >& rChartDoc, bool bIsChartex); @@ -219,12 +220,10 @@ private: void exportUpDownBars(const css::uno::Reference< css::chart2::XChartType >& xChartType ); void exportAllSeries(const css::uno::Reference<css::chart2::XChartType>& xChartType, bool& rPrimaryAxes); - void exportSeries_chart(const css::uno::Reference< css::chart2::XChartType >& xChartType, + void exportSeries(const css::uno::Reference< css::chart2::XChartType >& xChartType, const css::uno::Sequence<css::uno::Reference<css::chart2::XDataSeries> >& rSeriesSeq, - bool& rPrimaryAxes); - void exportSeries_chartex(const css::uno::Reference< css::chart2::XChartType >& xChartType, - const css::uno::Sequence<css::uno::Reference<css::chart2::XDataSeries> >& rSeriesSeq, - const char* sTypeName); + bool& rPrimaryAxes, + bool bIsChartex); void exportVaryColors(const css::uno::Reference<css::chart2::XChartType>& xChartType); void exportCandleStickSeries( diff --git a/include/test/xmltesttools.hxx b/include/test/xmltesttools.hxx index 555c64afe333..6a44b6c235b2 100644 --- a/include/test/xmltesttools.hxx +++ b/include/test/xmltesttools.hxx @@ -56,16 +56,6 @@ protected: { return getXPath(pXmlDoc, sXPath.getStr(), pAttribute); } - /** - * Same as above, but where the expected number of nodes with - * the given path is nNumPaths and the desired node index is nPathIdx. - */ - OUString getXPath(const xmlDocUniquePtr& pXmlDoc, const char* pXPath, int nNumPaths, int nPathIdx, const char* pAttribute); - OUString getXPath(const xmlDocUniquePtr& pXmlDoc, const OString& sXPath, int nNumPaths, int nPathIdx, const char* pAttribute) - { - assert(nPathIdx < nNumPaths); - return getXPath(pXmlDoc, sXPath.getStr(), nNumPaths, nPathIdx, pAttribute); - } /** * Same as the assertXPathContent(), but don't assert: return the string instead. */ @@ -116,19 +106,6 @@ protected: { assertXPathAttrs(pXmlDoc, sXPath.getStr(), aPairVector); } - /** - * Assert that pXPath exists, returns nNumNodes nodes, and the attribute - * value of node number nPathIdx equals the rExpected value. - */ - void assertXPath(const xmlDocUniquePtr& pXmlDoc, const char* pXPath, - int nNumNodes, int nNodeIdx, - const char* pAttribute, std::u16string_view rExpectedValue); - void assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& sXPath, - int nNumNodes, int nNodeIdx, - const char* pAttribute, std::u16string_view rExpectedValue) - { - assertXPath(pXmlDoc, sXPath.getStr(), nNumNodes, nNodeIdx, pAttribute, rExpectedValue); - } /** * Given a double for the rExpected value, assert that pXPath exists, returns exactly one node, diff --git a/oox/inc/drawingml/chart/chartspacemodel.hxx b/oox/inc/drawingml/chart/chartspacemodel.hxx index dc3ab8674634..d66abb21f9d7 100644 --- a/oox/inc/drawingml/chart/chartspacemodel.hxx +++ b/oox/inc/drawingml/chart/chartspacemodel.hxx @@ -39,7 +39,6 @@ struct ChartSpaceModel typedef ModelRef< View3DModel > View3DRef; typedef ModelRef< TitleModel > TitleRef; typedef ModelRef< LegendModel > LegendRef; - typedef ModelRef< DataSourceCxModel > DataSourceRef; ShapeRef mxShapeProp; /// Chart frame formatting. TextBodyRef mxTextProp; /// Global chart text formatting. @@ -60,7 +59,6 @@ struct ChartSpaceModel bool mbPlotVisOnly; /// True = plot visible cells in a sheet only. bool mbShowLabelsOverMax;/// True = show labels over chart maximum. bool mbPivotChart; /// True = pivot chart. - DataSourceRef maCxData; /// Data for Chartex. explicit ChartSpaceModel(bool bMSO2007Doc); ~ChartSpaceModel(); diff --git a/oox/inc/drawingml/chart/datasourcecontext.hxx b/oox/inc/drawingml/chart/datasourcecontext.hxx index eeeccb6d89b8..7edb029eb336 100644 --- a/oox/inc/drawingml/chart/datasourcecontext.hxx +++ b/oox/inc/drawingml/chart/datasourcecontext.hxx @@ -21,7 +21,6 @@ #define INCLUDED_OOX_DRAWINGML_CHART_DATASOURCECONTEXT_HXX #include <memory> -#include <oox/drawingml/chart/datasourcemodel.hxx> #include <drawingml/chart/chartcontextbase.hxx> class SvNumberFormatter; @@ -87,22 +86,6 @@ public: virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; }; -struct DataSourceCxModel; - -/** Handler for a chartex data source context (cx:chartData, cx:data elements). - */ -class DataSourceCxContext final : public ContextBase< DataSourceCxModel > -{ -public: - explicit DataSourceCxContext( ::oox::core::ContextHandler2Helper& rParent, - DataSourceCxModel& rModel); - virtual ~DataSourceCxContext() override; - - virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; - - DataSourceCxModel::DataSourceMap *paCurSource; -}; - } // namespace oox::drawingml::chart diff --git a/oox/inc/drawingml/chart/plotareaconverter.hxx b/oox/inc/drawingml/chart/plotareaconverter.hxx index 750d91cb916c..988405b3247c 100644 --- a/oox/inc/drawingml/chart/plotareaconverter.hxx +++ b/oox/inc/drawingml/chart/plotareaconverter.hxx @@ -21,8 +21,6 @@ #define INCLUDED_OOX_DRAWINGML_CHART_PLOTAREACONVERTER_HXX #include <drawingml/chart/converterbase.hxx> -#include <drawingml/chart/seriesmodel.hxx> -#include <oox/drawingml/chart/datasourcemodel.hxx> namespace com::sun::star { namespace chart2 { class XDiagram; } @@ -70,8 +68,7 @@ public: virtual ~PlotAreaConverter() override; /** Converts the OOXML plot area model to a chart2 diagram. */ - void convertFromModel( View3DModel& rView3DModel, - DataSourceCxModel& raDataMap ); + void convertFromModel( View3DModel& rView3DModel ); /** Converts the manual plot area position and size, if set. */ void convertPositionFromModel(); diff --git a/oox/inc/drawingml/chart/seriesconverter.hxx b/oox/inc/drawingml/chart/seriesconverter.hxx index 23a2c02cc7ef..c8cca31d5e3e 100644 --- a/oox/inc/drawingml/chart/seriesconverter.hxx +++ b/oox/inc/drawingml/chart/seriesconverter.hxx @@ -21,7 +21,6 @@ #define INCLUDED_OOX_DRAWINGML_CHART_SERIESCONVERTER_HXX #include <drawingml/chart/converterbase.hxx> -#include <oox/drawingml/chart/datasourcemodel.hxx> #include <drawingml/chart/seriesmodel.hxx> namespace com::sun::star { @@ -135,7 +134,7 @@ public: private: css::uno::Reference< css::chart2::data::XLabeledDataSequence > createLabeledDataSequence( - enum DataSourceType eSourceType, + SeriesModel::SourceType eSourceType, const OUString& rRole, bool bUseTextLabel ); }; diff --git a/oox/inc/drawingml/chart/seriesmodel.hxx b/oox/inc/drawingml/chart/seriesmodel.hxx index a42bf8b4036a..81c6e770ee1c 100644 --- a/oox/inc/drawingml/chart/seriesmodel.hxx +++ b/oox/inc/drawingml/chart/seriesmodel.hxx @@ -174,17 +174,17 @@ struct DataPointModel ~DataPointModel(); }; -enum class DataSourceType: sal_Int32 -{ - CATEGORIES, /// Data point categories. - VALUES, /// Data point values. - POINTS, /// Data point size (e.g. bubble size in bubble charts). - DATALABELS, /// Data point labels. -}; - struct SeriesModel { - typedef ModelMap< DataSourceType, DataSourceModel > DataSourceMap; + enum SourceType + { + CATEGORIES, /// Data point categories. + VALUES, /// Data point values. + POINTS, /// Data point size (e.g. bubble size in bubble charts). + DATALABELS, /// Data point labels. + }; + + typedef ModelMap< SourceType, DataSourceModel > DataSourceMap; typedef ModelVector< ErrorBarModel > ErrorBarVector; typedef ModelVector< TrendlineModel > TrendlineVector; typedef ModelVector< DataPointModel > DataPointVector; @@ -208,7 +208,6 @@ struct SeriesModel sal_Int32 mnMarkerSize; /// Size of the series line marker (2...72). sal_Int32 mnMarkerSymbol; /// Series line marker symbol. sal_Int32 mnOrder; /// Series order. - sal_Int32 mnDataId; /// Reference to correct data chunk (chartex) bool mbBubble3d; /// True = show bubbles with 3D shade. bool mbInvertNeg; /// True = invert negative data points. bool mbSmooth; /// True = smooth series line. diff --git a/oox/inc/drawingml/chart/typegroupconverter.hxx b/oox/inc/drawingml/chart/typegroupconverter.hxx index 720edf318a00..fac7eb70f7c4 100644 --- a/oox/inc/drawingml/chart/typegroupconverter.hxx +++ b/oox/inc/drawingml/chart/typegroupconverter.hxx @@ -21,8 +21,6 @@ #define INCLUDED_OOX_DRAWINGML_CHART_TYPEGROUPCONVERTER_HXX #include <drawingml/chart/converterbase.hxx> -#include <oox/drawingml/chart/datasourcemodel.hxx> -#include <drawingml/chart/seriesmodel.hxx> #include <com/sun/star/chart2/PieChartSubType.hpp> namespace com::sun::star { @@ -167,12 +165,6 @@ public: void convertPieExplosion( PropertySet& rPropSet, sal_Int32 nOoxExplosion ) const; /** Converts of-pie types */ css::chart2::PieChartSubType convertOfPieType(sal_Int32 nOoxOfPieType ) const; - /** Move any internal data to the appropriate series. In chartex the data - (if any is internal) is given outside the series, in a child element of - <cx:chartSpace>. Pre-2016 charts have the data inside the series, and - SeriesModel and subsequent handling reflects this. So this function gets - the data to the right place for processing. */ - void moveDataToSeries(DataSourceCxModel::DataMap& raDataMap); private: /** Inserts the passed series into the chart type. Adds additional properties to the series. */ diff --git a/oox/source/drawingml/chart/chartconverter.cxx b/oox/source/drawingml/chart/chartconverter.cxx index 1b281bd6cbc5..71f359d282fa 100644 --- a/oox/source/drawingml/chart/chartconverter.cxx +++ b/oox/source/drawingml/chart/chartconverter.cxx @@ -123,7 +123,6 @@ Reference< XDataSequence > ChartConverter::createDataSequence( { // create a single-row array from constant source data // (multiple levels in the case of complex categories) - assert( rDataSeq.mnPointCount > 0); std::vector<Any> aRow(rDataSeq.mnLevelCount * rDataSeq.mnPointCount); for (auto const& elem : rDataSeq.maData) aRow.at(elem.first) = elem.second; diff --git a/oox/source/drawingml/chart/chartspaceconverter.cxx b/oox/source/drawingml/chart/chartspaceconverter.cxx index 37111b865194..d2d51fad3c43 100644 --- a/oox/source/drawingml/chart/chartspaceconverter.cxx +++ b/oox/source/drawingml/chart/chartspaceconverter.cxx @@ -157,8 +157,7 @@ void ChartSpaceConverter::convertFromModel( const Reference< XShapes >& rxExtern bool bMSO2007Doc = getFilter().isMSO2007Document(); // convert plot area (container of all chart type groups) PlotAreaConverter aPlotAreaConv( *this, mrModel.mxPlotArea.getOrCreate() ); - aPlotAreaConv.convertFromModel( mrModel.mxView3D.getOrCreate(bMSO2007Doc), - mrModel.maCxData.getOrCreate()); + aPlotAreaConv.convertFromModel( mrModel.mxView3D.getOrCreate(bMSO2007Doc) ); // plot area converter has created the diagram object Reference< XDiagram > xDiagram = getChartDocument()->getFirstDiagram(); diff --git a/oox/source/drawingml/chart/chartspacefragment.cxx b/oox/source/drawingml/chart/chartspacefragment.cxx index f26b3cd924b4..29e77e4b5095 100644 --- a/oox/source/drawingml/chart/chartspacefragment.cxx +++ b/oox/source/drawingml/chart/chartspacefragment.cxx @@ -24,7 +24,6 @@ #include <drawingml/chart/chartspacemodel.hxx> #include <drawingml/chart/plotareacontext.hxx> #include <drawingml/chart/titlecontext.hxx> -#include <drawingml/chart/datasourcecontext.hxx> #include <oox/core/xmlfilterbase.hxx> #include <oox/helper/attributelist.hxx> #include <oox/token/namespaces.hxx> @@ -143,7 +142,8 @@ ContextHandlerRef ChartSpaceFragment::onCreateContext( sal_Int32 nElement, const case CX_TOKEN(chartSpace) : switch (nElement) { case CX_TOKEN(chartData): - return new DataSourceCxContext(*this, mrModel.maCxData.create()); + // TODO + return nullptr; case CX_TOKEN(chart): return this; case CX_TOKEN(spPr): diff --git a/oox/source/drawingml/chart/datasourcecontext.cxx b/oox/source/drawingml/chart/datasourcecontext.cxx index d27b715dbbc7..f4660f5db708 100644 --- a/oox/source/drawingml/chart/datasourcecontext.cxx +++ b/oox/source/drawingml/chart/datasourcecontext.cxx @@ -17,11 +17,10 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include <oox/drawingml/chart/datasourcemodel.hxx> - -#include <drawingml/chart/seriesmodel.hxx> #include <drawingml/chart/datasourcecontext.hxx> +#include <oox/drawingml/chart/datasourcemodel.hxx> + #include <oox/core/xmlfilterbase.hxx> #include <oox/helper/attributelist.hxx> #include <oox/token/namespaces.hxx> @@ -82,23 +81,6 @@ ContextHandlerRef DoubleSequenceContext::onCreateContext( sal_Int32 nElement, co return this; } break; - case CX_TOKEN(numDim) : - switch (nElement) { - case CX_TOKEN(f): - return this; - case CX_TOKEN(lvl): - mrModel.mnPointCount = rAttribs.getInteger(XML_ptCount, -1); - mrModel.maFormatCode = rAttribs.getString(XML_formatCode, ""); - return this; - } - break; - case CX_TOKEN(lvl) : - switch(nElement) { - case CX_TOKEN(pt): - mnPtIndex = rAttribs.getInteger(XML_idx, -1); - return this; - } - break; } return nullptr; } @@ -108,14 +90,12 @@ void DoubleSequenceContext::onCharacters( const OUString& rChars ) switch( getCurrentElement() ) { case C_TOKEN( f ): - case CX_TOKEN( f ): mrModel.maFormula = rChars; break; case C_TOKEN( formatCode ): mrModel.maFormatCode = rChars; break; case C_TOKEN( v ): - case CX_TOKEN(pt): if( mnPtIndex >= 0 ) { /* Import categories as String even though it could @@ -264,11 +244,9 @@ ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, co break; case C_TOKEN( lvl ): - case CX_TOKEN( lvl ): switch (nElement) { case C_TOKEN(pt): - case CX_TOKEN(pt): mnPtIndex = rAttribs.getInteger(XML_idx, -1); return this; } @@ -281,14 +259,6 @@ ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, co return this; } break; - case CX_TOKEN(strDim) : - switch (nElement) { - case CX_TOKEN(f): - return this; - case CX_TOKEN(lvl): - mrModel.mnPointCount = rAttribs.getInteger(XML_ptCount, -1); - return this; - } } return nullptr; } @@ -305,11 +275,8 @@ void StringSequenceContext::onCharacters( const OUString& rChars ) mrModel.maFormula = rChars; break; case C_TOKEN( v ): - case CX_TOKEN(pt): - if( mnPtIndex >= 0 ) { - assert(mrModel.mnPointCount > 0); + if( mnPtIndex >= 0 ) mrModel.maData[ (mrModel.mnLevelCount-1) * mrModel.mnPointCount + mnPtIndex ] <<= rChars; - } break; } } @@ -323,8 +290,7 @@ DataSourceContext::~DataSourceContext() { } -ContextHandlerRef DataSourceContext::onCreateContext( sal_Int32 nElement, const - AttributeList&) +ContextHandlerRef DataSourceContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) { switch( getCurrentElement() ) { @@ -364,74 +330,6 @@ ContextHandlerRef DataSourceContext::onCreateContext( sal_Int32 nElement, const return nullptr; } -// ===== -// DataSourceCxContext: handler for chartex data sources -// ===== -DataSourceCxContext::DataSourceCxContext( ContextHandler2Helper& rParent, - DataSourceCxModel& rModel ) : - ContextBase< DataSourceCxModel >( rParent, rModel ), - paCurSource(nullptr) -{ -} - -DataSourceCxContext::~DataSourceCxContext() -{ -} - -ContextHandlerRef DataSourceCxContext::onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs) -{ - switch( getCurrentElement() ) - { - case CX_TOKEN(chartData) : - switch (nElement) { - case CX_TOKEN(externalData) : - return nullptr; // TODO - case CX_TOKEN(data) : - paCurSource = &mrModel.maSourceMap.create(rAttribs.getInteger(XML_id, -1)); - return this; - } - break; - case CX_TOKEN(data) : - switch (nElement) { - case CX_TOKEN(numDim) : - { - assert(paCurSource); - OUString sType = rAttribs.getString(XML_type, "val"); - if (sType == "cat") { - DataSourceModel& rDataModel = paCurSource->create(DataSourceType::CATEGORIES); - return new DoubleSequenceContext(*this, - rDataModel.mxDataSeq.create()); - } else { - // default is VALUES - DataSourceModel& rDataModel = paCurSource->create(DataSourceType::VALUES); - return new DoubleSequenceContext(*this, - rDataModel.mxDataSeq.create()); - } - break; - } - - case CX_TOKEN(strDim) : - { - assert(paCurSource); - OUString sType = rAttribs.getString(XML_type, "cat"); - if (sType == "val") { - DataSourceModel& rDataModel = paCurSource->create(DataSourceType::VALUES); - return new StringSequenceContext(*this, - rDataModel.mxDataSeq.create()); - } else { - // default is CATEGORIES - DataSourceModel& rDataModel = paCurSource->create(DataSourceType::CATEGORIES); - return new StringSequenceContext(*this, - rDataModel.mxDataSeq.create()); - } - } - } - break; - - } - return nullptr; -} - } // namespace oox::drawingml::chart /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/chart/plotareaconverter.cxx b/oox/source/drawingml/chart/plotareaconverter.cxx index 95496906fdea..1fa8b6f9b673 100644 --- a/oox/source/drawingml/chart/plotareaconverter.cxx +++ b/oox/source/drawingml/chart/plotareaconverter.cxx @@ -32,7 +32,6 @@ #include <drawingml/chart/axisconverter.hxx> #include <drawingml/chart/plotareamodel.hxx> #include <drawingml/chart/typegroupconverter.hxx> -#include <drawingml/chart/seriesmodel.hxx> #include <oox/core/xmlfilterbase.hxx> #include <oox/token/namespaces.hxx> #include <oox/token/properties.hxx> @@ -72,7 +71,6 @@ public: const Reference< XDiagram >& rxDiagram, View3DModel& rView3DModel, sal_Int32 nAxesSetIdx, - DataSourceCxModel::DataMap& raSourceMap, bool bSupportsVaryColorsByPoint, bool bUseFixedInnerSize ); @@ -114,7 +112,6 @@ ModelRef< AxisModel > lclGetOrCreateAxis( const AxesSetModel::AxisMap& rFromAxes void AxesSetConverter::convertFromModel( const Reference< XDiagram >& rxDiagram, View3DModel& rView3DModel, sal_Int32 nAxesSetIdx, - DataSourceCxModel::DataMap& raSourceMap, bool bSupportsVaryColorsByPoint, bool bUseFixedInnerSize) { // create type group converter objects for all type groups @@ -172,13 +169,6 @@ void AxesSetConverter::convertFromModel( const Reference< XDiagram >& rxDiagram, to the data provider attached to the chart document. */ if( xCoordSystem.is() ) { - // Transfer any (chartex) data, specified at the chartSpace level, - // into the appropriate series. This needs to happen before the - // calls to AxisConverter::convertFromModel() below. - for (auto const& typeGroup : aTypeGroups) { - typeGroup->moveDataToSeries(raSourceMap); - } - bool bMSO2007Doc = getFilter().isMSO2007Document(); // convert all axes (create missing axis models) ModelRef< AxisModel > xXAxis = lclGetOrCreateAxis( mrModel.maAxes, API_X_AXIS, rFirstTypeGroup.getTypeInfo().mbCategoryAxis ? C_TOKEN( catAx ) : C_TOKEN( valAx ), bMSO2007Doc ); @@ -201,8 +191,7 @@ void AxesSetConverter::convertFromModel( const Reference< XDiagram >& rxDiagram, // convert all chart type groups, this converts all series data and formatting for (auto const& typeGroup : aTypeGroups) - typeGroup->convertFromModel( rxDiagram, xCoordSystem, - nAxesSetIdx,bSupportsVaryColorsByPoint ); + typeGroup->convertFromModel( rxDiagram, xCoordSystem, nAxesSetIdx, bSupportsVaryColorsByPoint ); } } catch( Exception& ) @@ -324,8 +313,7 @@ PlotAreaConverter::~PlotAreaConverter() { } -void PlotAreaConverter::convertFromModel( View3DModel& rView3DModel, - DataSourceCxModel& rDataCxModel ) +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. */ @@ -438,7 +426,7 @@ void PlotAreaConverter::convertFromModel( View3DModel& rView3DModel, { AxesSetConverter aAxesSetConv(*this, *axesSet); aAxesSetConv.convertFromModel(xDiagram, rView3DModel, nAxesSetIdx, - rDataCxModel.maSourceMap, bSupportsVaryColorsByPoint, bUseFixedInnerSize); + bSupportsVaryColorsByPoint, bUseFixedInnerSize); if(nAxesSetIdx == nStartAxesSetIdx) { maAutoTitle = aAxesSetConv.getAutomaticTitle(); diff --git a/oox/source/drawingml/chart/seriescontext.cxx b/oox/source/drawingml/chart/seriescontext.cxx index 19134c7a54a7..88688642bebe 100644 --- a/oox/source/drawingml/chart/seriescontext.cxx +++ b/oox/source/drawingml/chart/seriescontext.cxx @@ -452,10 +452,10 @@ ContextHandlerRef SeriesContextBase::onCreateContext( sal_Int32 nElement, const { case C_TOKEN( ext ): case CX_TOKEN( ext ): - if (mrModel.maSources.has( DataSourceType::DATALABELS )) + if (mrModel.maSources.has( SeriesModel::DATALABELS )) break; - DataSourceModel& rLabelsSource = mrModel.maSources.create( DataSourceType::DATALABELS ); + DataSourceModel& rLabelsSource = mrModel.maSources.create( SeriesModel::DATALABELS ); if (mrModel.mxLabels.is()) mrModel.mxLabels->mpLabelsSource = &rLabelsSource; return new DataSourceContext( *this, rLabelsSource ); @@ -483,7 +483,7 @@ ContextHandlerRef AreaSeriesContext::onCreateContext( sal_Int32 nElement, const switch( nElement ) { case C_TOKEN( cat ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::CATEGORIES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) ); case C_TOKEN( errBars ): return new ErrorBarContext( *this, mrModel.maErrorBars.create(bMSO2007Doc) ); case C_TOKEN( dLbls ): @@ -493,7 +493,7 @@ ContextHandlerRef AreaSeriesContext::onCreateContext( sal_Int32 nElement, const case C_TOKEN( trendline ): return new TrendlineContext( *this, mrModel.maTrendlines.create(bMSO2007Doc) ); case C_TOKEN( val ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::VALUES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) ); } break; } @@ -518,7 +518,7 @@ ContextHandlerRef BarSeriesContext::onCreateContext( sal_Int32 nElement, const A switch( nElement ) { case C_TOKEN( cat ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::CATEGORIES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) ); case C_TOKEN( dLbls ): return new DataLabelsContext( *this, mrModel.mxLabels.create(bMSO2007Doc) ); case C_TOKEN( dPt ): @@ -536,7 +536,7 @@ ContextHandlerRef BarSeriesContext::onCreateContext( sal_Int32 nElement, const A case C_TOKEN( trendline ): return new TrendlineContext( *this, mrModel.maTrendlines.create(bMSO2007Doc) ); case C_TOKEN( val ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::VALUES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) ); } break; } @@ -564,7 +564,7 @@ ContextHandlerRef BubbleSeriesContext::onCreateContext( sal_Int32 nElement, cons mrModel.mbBubble3d = rAttribs.getBool( XML_val, !bMSO2007Doc ); return nullptr; case C_TOKEN( bubbleSize ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::POINTS ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::POINTS ) ); case C_TOKEN( dLbls ): return new DataLabelsContext( *this, mrModel.mxLabels.create(bMSO2007Doc) ); case C_TOKEN( dPt ): @@ -577,9 +577,9 @@ ContextHandlerRef BubbleSeriesContext::onCreateContext( sal_Int32 nElement, cons case C_TOKEN( trendline ): return new TrendlineContext( *this, mrModel.maTrendlines.create(bMSO2007Doc) ); case C_TOKEN( xVal ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::CATEGORIES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) ); case C_TOKEN( yVal ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::VALUES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) ); } break; } @@ -604,7 +604,7 @@ ContextHandlerRef LineSeriesContext::onCreateContext( sal_Int32 nElement, const switch( nElement ) { case C_TOKEN( cat ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::CATEGORIES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) ); case C_TOKEN( dLbls ): return new DataLabelsContext( *this, mrModel.mxLabels.create(bMSO2007Doc) ); case C_TOKEN( dPt ): @@ -619,7 +619,7 @@ ContextHandlerRef LineSeriesContext::onCreateContext( sal_Int32 nElement, const case C_TOKEN( trendline ): return new TrendlineContext( *this, mrModel.maTrendlines.create(bMSO2007Doc) ); case C_TOKEN( val ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::VALUES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) ); } break; } @@ -644,7 +644,7 @@ ContextHandlerRef PieSeriesContext::onCreateContext( sal_Int32 nElement, const A switch( nElement ) { case C_TOKEN( cat ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::CATEGORIES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) ); case C_TOKEN( dLbls ): return new DataLabelsContext( *this, mrModel.mxLabels.create(bMSO2007Doc) ); case C_TOKEN( dPt ): @@ -653,7 +653,7 @@ ContextHandlerRef PieSeriesContext::onCreateContext( sal_Int32 nElement, const A mrModel.mnExplosion = rAttribs.getInteger( XML_val, 0 ); return nullptr; case C_TOKEN( val ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::VALUES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) ); } break; } @@ -678,7 +678,7 @@ ContextHandlerRef RadarSeriesContext::onCreateContext( sal_Int32 nElement, const switch( nElement ) { case C_TOKEN( cat ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::CATEGORIES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) ); case C_TOKEN( dLbls ): return new DataLabelsContext( *this, mrModel.mxLabels.create(bMSO2007Doc) ); case C_TOKEN( dPt ): @@ -689,7 +689,7 @@ ContextHandlerRef RadarSeriesContext::onCreateContext( sal_Int32 nElement, const mrModel.mbSmooth = rAttribs.getBool( XML_val, bMSO2007Doc ); return nullptr; case C_TOKEN( val ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::VALUES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) ); } break; } @@ -727,9 +727,9 @@ ContextHandlerRef ScatterSeriesContext::onCreateContext( sal_Int32 nElement, con case C_TOKEN( trendline ): return new TrendlineContext( *this, mrModel.maTrendlines.create(bMSO2007Doc) ); case C_TOKEN( xVal ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::CATEGORIES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) ); case C_TOKEN( yVal ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::VALUES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) ); } break; } @@ -753,9 +753,9 @@ ContextHandlerRef SurfaceSeriesContext::onCreateContext( sal_Int32 nElement, con switch( nElement ) { case C_TOKEN( cat ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::CATEGORIES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::CATEGORIES ) ); case C_TOKEN( val ): - return new DataSourceContext( *this, mrModel.maSources.create( DataSourceType::VALUES ) ); + return new DataSourceContext( *this, mrModel.maSources.create( SeriesModel::VALUES ) ); } break; } @@ -789,7 +789,7 @@ ContextHandlerRef ChartexSeriesContext::onCreateContext( sal_Int32 nElement, con case CX_TOKEN( dataLabels ): return new DataLabelsContext( *this, mrModel.mxLabels.create(false) ); case CX_TOKEN( dataId ): - mrModel.mnDataId = rAttribs.getInteger(XML_val, -1); + // TODO return nullptr; case CX_TOKEN( layoutPr ): // This looks complicated. TODO diff --git a/oox/source/drawingml/chart/seriesconverter.cxx b/oox/source/drawingml/chart/seriesconverter.cxx index 4b8674ece646..cef5608294c1 100644 --- a/oox/source/drawingml/chart/seriesconverter.cxx +++ b/oox/source/drawingml/chart/seriesconverter.cxx @@ -816,12 +816,12 @@ SeriesConverter::~SeriesConverter() Reference< XLabeledDataSequence > SeriesConverter::createCategorySequence( const OUString& rRole ) { - return createLabeledDataSequence(DataSourceType::CATEGORIES, rRole, false); + return createLabeledDataSequence(SeriesModel::CATEGORIES, rRole, false); } Reference< XLabeledDataSequence > SeriesConverter::createValueSequence( const OUString& rRole ) { - return createLabeledDataSequence( DataSourceType::VALUES, rRole, true ); + return createLabeledDataSequence( SeriesModel::VALUES, rRole, true ); } Reference< XDataSeries > SeriesConverter::createDataSeries( const TypeGroupConverter& rTypeGroup, bool bVaryColorsByPoint ) @@ -861,8 +861,7 @@ Reference< XDataSeries > SeriesConverter::createDataSeries( const TypeGroupConve // add size values of bubble charts if( rTypeInfo.meTypeId == TYPEID_BUBBLE ) { - Reference< XLabeledDataSequence > xSizeValueSeq = - createLabeledDataSequence( DataSourceType::POINTS, u"values-size"_ustr, true ); + Reference< XLabeledDataSequence > xSizeValueSeq = createLabeledDataSequence( SeriesModel::POINTS, u"values-size"_ustr, true ); if( xSizeValueSeq.is() ) aLabeledSeqVec.push_back( xSizeValueSeq ); } @@ -954,7 +953,7 @@ Reference< XDataSeries > SeriesConverter::createDataSeries( const TypeGroupConve if( xLabels->maNumberFormat.maFormatCode.isEmpty() ) { // Use number format code from Value series - DataSourceModel* pValues = mrModel.maSources.get( DataSourceType::VALUES ).get(); + DataSourceModel* pValues = mrModel.maSources.get( SeriesModel::VALUES ).get(); if( pValues ) xLabels->maNumberFormat.maFormatCode = pValues->mxDataSeq->maFormatCode; } @@ -968,7 +967,7 @@ Reference< XDataSeries > SeriesConverter::createDataSeries( const TypeGroupConve // private -------------------------------------------------------------------- Reference< XLabeledDataSequence > SeriesConverter::createLabeledDataSequence( - enum DataSourceType eSourceType, const OUString& rRole, bool bUseTextLabel ) + SeriesModel::SourceType eSourceType, const OUString& rRole, bool bUseTextLabel ) { DataSourceModel* pValues = mrModel.maSources.get( eSourceType ).get(); TextModel* pTitle = bUseTextLabel ? mrModel.mxText.get() : nullptr; diff --git a/oox/source/drawingml/chart/seriesmodel.cxx b/oox/source/drawingml/chart/seriesmodel.cxx index 194d4f6ecf3d..95b0deb225e7 100644 --- a/oox/source/drawingml/chart/seriesmodel.cxx +++ b/oox/source/drawingml/chart/seriesmodel.cxx @@ -112,7 +112,6 @@ SeriesModel::SeriesModel(bool bMSO2007Doc) : mnMarkerSize( 5 ), mnMarkerSymbol( XML_auto ), mnOrder( -1 ), - mnDataId(-1), mbBubble3d( !bMSO2007Doc ), mbInvertNeg( !bMSO2007Doc ), mbSmooth( !bMSO2007Doc ) diff --git a/oox/source/drawingml/chart/typegroupconverter.cxx b/oox/source/drawingml/chart/typegroupconverter.cxx index c2313cd502ec..0202bde7ac0b 100644 --- a/oox/source/drawingml/chart/typegroupconverter.cxx +++ b/oox/source/drawingml/chart/typegroupconverter.cxx @@ -39,7 +39,6 @@ #include <comphelper/sequence.hxx> #include <osl/diagnose.h> #include <drawingml/lineproperties.hxx> -#include <drawingml/chart/seriesmodel.hxx> #include <drawingml/chart/seriesconverter.hxx> #include <drawingml/chart/typegroupmodel.hxx> #include <oox/core/xmlfilterbase.hxx> @@ -292,16 +291,16 @@ Reference< XLabeledDataSequence > TypeGroupConverter::createCategorySequence() first series, even if it was empty. */ for (auto const& elem : mrModel.maSeries) { - if( elem->maSources.has( DataSourceType::CATEGORIES ) ) + if( elem->maSources.has( SeriesModel::CATEGORIES ) ) { SeriesConverter aSeriesConv(*this, *elem); xLabeledSeq = aSeriesConv.createCategorySequence( u"categories"_ustr ); if (xLabeledSeq.is()) break; } - else if( nMaxValues <= 0 && elem->maSources.has( DataSourceType::VALUES ) ) + else if( nMaxValues <= 0 && elem->maSources.has( SeriesModel::VALUES ) ) { - DataSourceModel *pValues = elem->maSources.get( DataSourceType::VALUES ).get(); + DataSourceModel *pValues = elem->maSources.get( SeriesModel::VALUES ).get(); if( pValues->mxDataSeq.is() ) nMaxValues = pValues->mxDataSeq->maData.size(); } @@ -312,9 +311,9 @@ Reference< XLabeledDataSequence > TypeGroupConverter::createCategorySequence() nMaxValues = 2; typedef RefVector<SeriesModel> SeriesModelVector; SeriesModelVector::value_type aModel = mrModel.maSeries.get(0); - if (!aModel->maSources.has(DataSourceType::CATEGORIES)) + if (!aModel->maSources.has(SeriesModel::CATEGORIES)) { - DataSourceModel &aSrc = aModel->maSources.create( DataSourceType::CATEGORIES ); + DataSourceModel &aSrc = aModel->maSources.create( SeriesModel::CATEGORIES ); DataSequenceModel &aSeq = aSrc.mxDataSeq.create(); aSeq.mnPointCount = nMaxValues; for( sal_Int32 i = 0; i < nMaxValues; i++ ) @@ -328,8 +327,7 @@ Reference< XLabeledDataSequence > TypeGroupConverter::createCategorySequence() void TypeGroupConverter::convertFromModel( const Reference< XDiagram >& rxDiagram, const Reference< XCoordinateSystem >& rxCoordSystem, - sal_Int32 nAxesSetIdx, - bool bSupportsVaryColorsByPoint ) + sal_Int32 nAxesSetIdx, bool bSupportsVaryColorsByPoint ) { try { @@ -626,22 +624,6 @@ PieChartSubType TypeGroupConverter::convertOfPieType(sal_Int32 nOoxOfPieType ) c } } -void TypeGroupConverter::moveDataToSeries(DataSourceCxModel::DataMap& raDataMap) -{ - // For chartex, move data from rDataMap to the appropriate series. In - // chartex the data is given outside the series, in a child element of - // <cx:chartSpace>. Pre-2016 charts have the data inside the series, and - // SeriesModel and subsequent handling reflects this. So here we get the - // data to the right place for processing. - if (!raDataMap.empty()) { - // should only happen for chartex - for (auto const& elem : mrModel.maSeries) { - // This ID must be present in the map - assert(raDataMap.find(elem->mnDataId) != raDataMap.end()); - elem->maSources = *(raDataMap[elem->mnDataId]); - } - } -} // private -------------------------------------------------------------------- diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index 45c1adcaf7c8..1ab0e09ca228 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -231,65 +231,11 @@ void outputDataPointStyleEntry(FSHelperPtr pFS) pFS->endElement(FSNS(XML_cs, XML_dataPoint)); } -std::vector<Sequence<Reference<chart2::XDataSeries> > > splitDataSeriesByAxis(const Reference< chart2::XChartType >& xChartType) -{ - std::vector<Sequence<Reference<chart2::XDataSeries> > > aSplitSeries; - std::map<sal_Int32, size_t> aMapAxisToIndex; - - Reference< chart2::XDataSeriesContainer > xDSCnt(xChartType, uno::UNO_QUERY); - if (xDSCnt.is()) - { - sal_Int32 nAxisIndexOfFirstSeries = -1; - const Sequence< Reference< chart2::XDataSeries > > aSeriesSeq(xDSCnt->getDataSeries()); - for (const uno::Reference<chart2::XDataSeries>& xSeries : aSeriesSeq) - { - Reference<beans::XPropertySet> xPropSet(xSeries, uno::UNO_QUERY); - if (!xPropSet.is()) - continue; - - sal_Int32 nAxisIndex = -1; - uno::Any aAny = xPropSet->getPropertyValue(u"AttachedAxisIndex"_ustr); - aAny >>= nAxisIndex; - size_t nVectorPos = 0; - if (nAxisIndexOfFirstSeries == -1) - { - nAxisIndexOfFirstSeries = nAxisIndex; - } - - auto it = aMapAxisToIndex.find(nAxisIndex); - if (it == aMapAxisToIndex.end()) - { - aSplitSeries.emplace_back(); - nVectorPos = aSplitSeries.size() - 1; - aMapAxisToIndex.insert(std::pair<sal_Int32, size_t>(nAxisIndex, nVectorPos)); - } - else - { - nVectorPos = it->second; - } - - uno::Sequence<Reference<chart2::XDataSeries> >& rAxisSeriesSeq = aSplitSeries[nVectorPos]; - sal_Int32 nLength = rAxisSeriesSeq.getLength(); - rAxisSeriesSeq.realloc(nLength + 1); - rAxisSeriesSeq.getArray()[nLength] = xSeries; - } - // if the first series attached to secondary axis, then export those series first, which are attached to primary axis - // also the MS Office export every time in this order - if (aSplitSeries.size() > 1 && nAxisIndexOfFirstSeries == 1) - { - std::swap(aSplitSeries[0], aSplitSeries[1]); - } - } - - return aSplitSeries; } -} // unnamed namespace - -static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( - const Reference< chart2::XDiagram > & xDiagram, bool *pbHasDateCategories ) +static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram, bool& bHasDateCategories ) { - *pbHasDateCategories = false; + bHasDateCategories = false; Reference< chart2::data::XLabeledDataSequence > xResult; try { @@ -312,7 +258,7 @@ static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( chart2::ScaleData aScaleData = xAxis->getScaleData(); if( aScaleData.Categories.is()) { - *pbHasDateCategories = aScaleData.AxisType == chart2::AxisType::DATE; + bHasDateCategories = aScaleData.AxisType == chart2::AxisType::DATE; xResult.set( aScaleData.Categories ); break; } @@ -352,8 +298,7 @@ static bool lcl_hasCategoryLabels( const Reference< chart2::XChartDocument >& xC //categories are always the first sequence Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram()); bool bDateCategories; - Reference< chart2::data::XLabeledDataSequence > xCategories( - lcl_getCategories( xDiagram, &bDateCategories ) ); + Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram, bDateCategories ) ); return xCategories.is(); } @@ -1327,7 +1272,7 @@ void ChartExport::exportChartSpace( const Reference< css::chart::XChartDocument pFS->startElement(FSNS(XML_cx, XML_chartData)); exportExternalData(xChartDoc, true); - exportData_chartex(xChartDoc); + exportData(xChartDoc, true); pFS->endElement(FSNS(XML_cx, XML_chartData)); } else { @@ -1376,238 +1321,22 @@ void ChartExport::exportChartSpace( const Reference< css::chart::XChartDocument pFS->endElement( FSNS( nChartNS, XML_chartSpace ) ); } -void ChartExport::exportData_chartex( [[maybe_unused]] const Reference< css::chart::XChartDocument >& xChartDoc) +void ChartExport::exportData( [[maybe_unused]] const Reference< css::chart::XChartDocument >& xChartDoc, + bool bIsChartex) { - Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( mxNewDiagram, uno::UNO_QUERY ); - if( ! xBCooSysCnt.is()) return; - const Sequence< Reference< chart2::XCoordinateSystem > > - aCooSysSeq( xBCooSysCnt->getCoordinateSystems()); - - if (!aCooSysSeq.hasElements()) return; - - for( const auto& rCS : aCooSysSeq ) { - Reference< chart2::XChartTypeContainer > xCTCnt( rCS, uno::UNO_QUERY ); - if( ! xCTCnt.is()) - continue; - const Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes()); - - for( const auto& rCT : aCTSeq ) { - Reference< chart2::XDataSeriesContainer > xDSCnt( rCT, uno::UNO_QUERY ); - if( ! xDSCnt.is()) - return; - Reference< chart2::XChartType > xChartType( rCT, uno::UNO_QUERY ); - if( ! xChartType.is()) - continue; - - OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel(); - - const std::vector<Sequence<Reference<chart2::XDataSeries> > > aSplitDataSeries = splitDataSeriesByAxis(xChartType); - - for (const auto& splitDataSeries : aSplitDataSeries) { - sal_Int32 nSeriesIndex = 0; - for( const auto& rSeries : splitDataSeries ) - { - // export series - Reference< chart2::data::XDataSource > xSource( rSeries, uno::UNO_QUERY ); - if( !xSource.is()) continue; - - Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt( - xSource->getDataSequences()); - - // search for main sequence and create a series element - sal_Int32 nMainSequenceIndex = -1; - sal_Int32 nSeriesLength = 0; - Reference< chart2::data::XDataSequence > xValueSeq; - Reference< chart2::data::XDataSequence > xLabelSeq; - sal_Int32 nSeqIdx=0; - for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx ) - { - Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() ); - if( nMainSequenceIndex==-1 ) - { - Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY ); - OUString aRole; - if( xSeqProp.is()) - xSeqProp->getPropertyValue(u"Role"_ustr) >>= aRole; - // "main" sequence - if( aRole == aLabelRole ) - { - xValueSeq.set( xTempValueSeq ); - xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel()); - nMainSequenceIndex = nSeqIdx; - } - } - sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0)); - if( nSeriesLength < nSequenceLength ) - nSeriesLength = nSequenceLength; - } - FSHelperPtr pFS = GetFS(); - - // The data id needs to agree with the id in exportSeries(). See DATA_ID_COMMENT - pFS->startElement(FSNS(XML_cx, XML_data), XML_id, OUString::number(nSeriesIndex++)); - - // .xlsx chartex files seem to have this magical "_xlchart.v2.0" string, - // and no explicit data, while .docx and .pptx contain the literal data, - // as well as a ../embeddings file (which LO doesn't seem to produce). - // But there's probably a smarter way to determine which pathway to take - // than based on document type. - if (GetDocumentType() == DOCUMENT_XLSX) { - // Just hard-coding this for now - pFS->startElement(FSNS(XML_cx, XML_numDim), XML_type, "val"); - pFS->startElement(FSNS(XML_cx, XML_f)); - pFS->writeEscaped("_xlchart.v2.0"); // I have no idea what this - // means or what it should be in - // general - pFS->endElement(FSNS(XML_cx, XML_f)); - pFS->endElement(FSNS(XML_cx, XML_numDim)); - } else { // PPTX, DOCX - OUString aCellRange = mxCategoriesValues.is() ? mxCategoriesValues->getSourceRangeRepresentation() : OUString(); -#undef OUTPUT_SPLIT_CATEGORIES // do we need this or not? TODO -#ifdef OUTPUT_SPLIT_CATEGORIES - const Sequence< Sequence< OUString >> aFinalSplitSource = getSplitCategoriesList(aCellRange); -#endif - aCellRange = parseFormula( aCellRange ); - -#ifdef OUTPUT_SPLIT_CATEGORIES - if (aFinalSplitSource.getLength() > 1) { - - // export multi level category axis labels - pFS->startElement(FSNS(XML_cx, XML_strDim), XML_type, "cat"); - - pFS->startElement(FSNS(XML_cx, XML_f)); - pFS->writeEscaped(aCellRange); - pFS->endElement(FSNS(XML_cx, XML_f)); - - for (const auto& rSeq : aFinalSplitSource) { - pFS->startElement(FSNS(XML_cx, XML_lvl), - XML_ptCount, OString::number(aFinalSplitSource[0].getLength())); - - for (sal_Int32 j = 0; j < rSeq.getLength(); j++) { - if(!rSeq[j].isEmpty()) { - pFS->startElement(FSNS(XML_cx, XML_pt), XML_idx, OString::number(j)); - pFS->writeEscaped(rSeq[j]); - pFS->endElement(FSNS(XML_cx, XML_pt)); - } - } - pFS->endElement(FSNS(XML_cx, XML_lvl)); - } - - pFS->endElement(FSNS(XML_cx, XML_strDim)); - } - else -#endif - { - // export single category axis labels - // TODO: seems like this should consider mbHasCategoryLabels - bool bWriteDateCategories = mbHasDateCategories; - OUString aNumberFormatString; - if (bWriteDateCategories) - { - Reference< css::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY ); - if( xAxisXSupp.is()) - { - Reference< XPropertySet > xAxisProp = xAxisXSupp->getXAxis(); - if (GetProperty(xAxisProp, u"NumberFormat"_ustr)) - { - sal_Int32 nKey = 0; - mAny >>= nKey; - aNumberFormatString = getNumberFormatCode(nKey); - } - } - if (aNumberFormatString.isEmpty()) bWriteDateCategories = false; - } - - // === Output the categories - if (bWriteDateCategories) - { - std::vector<double> aDateCategories = lcl_getAllValuesFromSequence(xValueSeq); - const sal_Int32 ptCount = aDateCategories.size(); - - pFS->startElement(FSNS(XML_cx, XML_numDim), XML_type, "x"); // is "x" right? - // TODO: check this - - pFS->startElement(FSNS(XML_cx, XML_f)); - pFS->writeEscaped(aCellRange); - pFS->endElement(FSNS(XML_cx, XML_f)); - - pFS->startElement(FSNS(XML_cx, XML_lvl), - XML_ptCount, OString::number(ptCount), - XML_formatCode, aNumberFormatString); - - for (sal_Int32 i = 0; i < ptCount; i++) { - if (!std::isnan(aDateCategories[i])) { - pFS->startElement(FSNS(XML_cx, XML_pt), XML_idx, OString::number(i)); - pFS->write(OString::number(aDateCategories[i])); - pFS->endElement(FSNS(XML_cx, XML_pt)); - } - } - - pFS->endElement(FSNS(XML_cx, XML_lvl)); - pFS->endElement(FSNS(XML_cx, XML_numDim)); - } - else - { - std::vector<OUString> aCategories; - lcl_fillCategoriesIntoStringVector(xValueSeq, aCategories); - const sal_Int32 ptCount = aCategories.size(); - - // TODO: shouldn't have "cat" hard-coded here: - // other options are colorStr, entityId - pFS->startElement(FSNS(XML_cx, XML_strDim), XML_type, "cat"); - - pFS->startElement(FSNS(XML_cx, XML_f)); - pFS->writeEscaped(aCellRange); - pFS->endElement(FSNS(XML_cx, XML_f)); - - pFS->startElement(FSNS(XML_cx, XML_lvl), XML_ptCount, OString::number(ptCount)); - - for (sal_Int32 i = 0; i < ptCount; i++) { - pFS->startElement(FSNS(XML_cx, XML_pt), XML_idx, OString::number(i)); - pFS->writeEscaped(aCategories[i]); - pFS->endElement(FSNS(XML_cx, XML_pt)); - } - - pFS->endElement(FSNS(XML_cx, XML_lvl)); - pFS->endElement(FSNS(XML_cx, XML_strDim)); - } - - // === Output the values - pFS->startElement(FSNS(XML_cx, XML_numDim), XML_type, "val"); - - aCellRange = xValueSeq.is() ? xValueSeq->getSourceRangeRepresentation() : OUString(); - aCellRange = parseFormula( aCellRange ); - // TODO: need to handle XML_multiLvlStrRef according to aCellRange - - pFS->startElement(FSNS(XML_cx, XML_f)); - pFS->writeEscaped( aCellRange ); - pFS->endElement( FSNS( XML_cx, XML_f ) ); - - ::std::vector< double > aValues = lcl_getAllValuesFromSequence( xValueSeq ); - sal_Int32 ptCount = aValues.size(); - OUString sNumberFormatString(u"General"_ustr); - const sal_Int32 nKey = xValueSeq.is() ? xValueSeq->getNumberFormatKeyByIndex(-1) : 0; - if (nKey > 0) { - sNumberFormatString = getNumberFormatCode(nKey); - } - pFS->startElement(FSNS(XML_cx, XML_lvl), - XML_ptCount, OString::number(ptCount), - XML_formatCode, sNumberFormatString); - - for( sal_Int32 i = 0; i < ptCount; i++ ) { - - pFS->startElement(FSNS(XML_cx, XML_pt), XML_idx, OString::number(i)); - pFS->write(std::isnan(aValues[i]) ? 0 : aValues[i]); - pFS->endElement(FSNS(XML_cx, XML_pt)); - } - - pFS->endElement(FSNS(XML_cx, XML_lvl)); - pFS->endElement(FSNS(XML_cx, XML_numDim)); - } - } - pFS->endElement(FSNS(XML_cx, XML_data)); - } - } - } + if (bIsChartex) { + FSHelperPtr pFS = GetFS(); + + pFS->startElement(FSNS(XML_cx, XML_data), XML_id, "0"); + // Just hard-coding this for now + pFS->startElement(FSNS(XML_cx, XML_numDim), XML_type, "val"); + pFS->startElement(FSNS(XML_cx, XML_f)); + pFS->writeEscaped("_xlchart.v2.0"); // I have no idea what this + // means or what it should be in + // general + pFS->endElement(FSNS(XML_cx, XML_f)); + pFS->endElement(FSNS(XML_cx, XML_numDim)); + pFS->endElement(FSNS(XML_cx, XML_data)); } } @@ -2311,6 +2040,63 @@ void ChartExport::exportTitle( const Reference< XShape >& xShape, bool bIsCharte } } +namespace { + + std::vector<Sequence<Reference<chart2::XDataSeries> > > splitDataSeriesByAxis(const Reference< chart2::XChartType >& xChartType) + { + std::vector<Sequence<Reference<chart2::XDataSeries> > > aSplitSeries; + std::map<sal_Int32, size_t> aMapAxisToIndex; + + Reference< chart2::XDataSeriesContainer > xDSCnt(xChartType, uno::UNO_QUERY); + if (xDSCnt.is()) + { + sal_Int32 nAxisIndexOfFirstSeries = -1; + const Sequence< Reference< chart2::XDataSeries > > aSeriesSeq(xDSCnt->getDataSeries()); + for (const uno::Reference<chart2::XDataSeries>& xSeries : aSeriesSeq) + { + Reference<beans::XPropertySet> xPropSet(xSeries, uno::UNO_QUERY); + if (!xPropSet.is()) + continue; + + sal_Int32 nAxisIndex = -1; + uno::Any aAny = xPropSet->getPropertyValue(u"AttachedAxisIndex"_ustr); + aAny >>= nAxisIndex; + size_t nVectorPos = 0; + if (nAxisIndexOfFirstSeries == -1) + { + nAxisIndexOfFirstSeries = nAxisIndex; + } + + auto it = aMapAxisToIndex.find(nAxisIndex); + if (it == aMapAxisToIndex.end()) + { + aSplitSeries.emplace_back(); + nVectorPos = aSplitSeries.size() - 1; + aMapAxisToIndex.insert(std::pair<sal_Int32, size_t>(nAxisIndex, nVectorPos)); + } + else + { + nVectorPos = it->second; + } + + uno::Sequence<Reference<chart2::XDataSeries> >& rAxisSeriesSeq = aSplitSeries[nVectorPos]; + sal_Int32 nLength = rAxisSeriesSeq.getLength(); + rAxisSeriesSeq.realloc(nLength + 1); + rAxisSeriesSeq.getArray()[nLength] = xSeries; + } + // if the first series attached to secondary axis, then export those series first, which are attached to primary axis + // also the MS Office export every time in this order + if (aSplitSeries.size() > 1 && nAxisIndexOfFirstSeries == 1) + { + std::swap(aSplitSeries[0], aSplitSeries[1]); + } + } + + return aSplitSeries; + } + +} + void ChartExport::exportPlotArea(const Reference< css::chart::XChartDocument >& xChartDoc, bool bIsChartex) { @@ -2869,10 +2655,9 @@ void ChartExport::exportAreaChart( const Reference< chart2::XChartType >& xChart exportGrouping(); bool bPrimaryAxes = true; if (splitDataSeries.hasElements()) - exportSeries_chart(xChartType, splitDataSeries, bPrimaryAxes); + exportSeries(xChartType, splitDataSeries, bPrimaryAxes, false); createAxes(bPrimaryAxes, false); - //exportAxesId(bPrimaryAxes); pFS->endElement(FSNS(XML_c, nTypeId)); } @@ -2909,7 +2694,7 @@ void ChartExport::exportBarChart(const Reference< chart2::XChartType >& xChartTy bool bPrimaryAxes = true; if (splitDataSeries.hasElements()) - exportSeries_chart(xChartType, splitDataSeries, bPrimaryAxes); + exportSeries(xChartType, splitDataSeries, bPrimaryAxes, false); Reference< XPropertySet > xTypeProp(xChartType, uno::UNO_QUERY); @@ -2998,7 +2783,7 @@ void ChartExport::exportBubbleChart( const Reference< chart2::XChartType >& xCha bool bPrimaryAxes = true; if (splitDataSeries.hasElements()) - exportSeries_chart(xChartType, splitDataSeries, bPrimaryAxes); + exportSeries(xChartType, splitDataSeries, bPrimaryAxes, false); createAxes(bPrimaryAxes, false); @@ -3015,9 +2800,14 @@ void ChartExport::exportFunnelChart( const Reference< chart2::XChartType >& xCha if (!splitDataSeries.hasElements()) continue; + pFS->startElement(FSNS(XML_cx, XML_series), XML_layoutId, "funnel"); + //exportVaryColors(xChartType); - exportSeries_chartex(xChartType, splitDataSeries, "funnel"); + bool bPrimaryAxes = false; + exportSeries(xChartType, splitDataSeries, bPrimaryAxes, true); + + pFS->endElement(FSNS(XML_cx, XML_series)); } } @@ -3118,7 +2908,7 @@ void ChartExport::exportLineChart( const Reference< chart2::XChartType >& xChart // TODO: show marker symbol in series? bool bPrimaryAxes = true; if (splitDataSeries.hasElements()) - exportSeries_chart(xChartType, splitDataSeries, bPrimaryAxes); + exportSeries(xChartType, splitDataSeries, bPrimaryAxes, false); // show marker? sal_Int32 nSymbolType = css::chart::ChartSymbolType::NONE; @@ -3208,9 +2998,8 @@ void ChartExport::exportScatterChartSeries( const Reference< chart2::XChartType // FIXME: should export xVal and yVal bool bPrimaryAxes = true; if (pSeries) - exportSeries_chart(xChartType, *pSeries, bPrimaryAxes); + exportSeries(xChartType, *pSeries, bPrimaryAxes, false); createAxes(bPrimaryAxes, false); - //exportAxesId(bPrimaryAxes); pFS->endElement( FSNS( XML_c, XML_scatterChart ) ); } @@ -3346,7 +3135,7 @@ void ChartExport::exportAllSeries(const Reference<chart2::XChartType>& xChartTyp // export dataseries for current chart-type Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries()); - exportSeries_chart(xChartType, aSeriesSeq, rPrimaryAxes); + exportSeries(xChartType, aSeriesSeq, rPrimaryAxes, false); } void ChartExport::exportVaryColors(const Reference<chart2::XChartType>& xChartType) @@ -3367,9 +3156,10 @@ void ChartExport::exportVaryColors(const Reference<chart2::XChartType>& xChartTy } } -void ChartExport::exportSeries_chart( const Reference<chart2::XChartType>& xChartType, +void ChartExport::exportSeries( const Reference<chart2::XChartType>& xChartType, const Sequence<Reference<chart2::XDataSeries> >& rSeriesSeq, - bool& rPrimaryAxes) + bool& rPrimaryAxes, + bool bIsChartex) { OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel(); OUString aChartType( xChartType->getChartType()); @@ -3417,17 +3207,19 @@ void ChartExport::exportSeries_chart( const Reference<chart2::XChartType>& xChar // xLabelSeq contain those. Otherwise both are empty FSHelperPtr pFS = GetFS(); - pFS->startElement(FSNS(XML_c, XML_ser)); + if (!bIsChartex) { + pFS->startElement(FSNS(XML_c, XML_ser)); - // TODO: idx and order - pFS->singleElement( FSNS( XML_c, XML_idx ), - XML_val, OString::number(mnSeriesCount) ); - pFS->singleElement( FSNS( XML_c, XML_order ), - XML_val, OString::number(mnSeriesCount++) ); + // TODO: idx and order + pFS->singleElement( FSNS( XML_c, XML_idx ), + XML_val, OString::number(mnSeriesCount) ); + pFS->singleElement( FSNS( XML_c, XML_order ), + XML_val, OString::number(mnSeriesCount++) ); + } // export label if( xLabelSeq.is() ) - exportSeriesText( xLabelSeq, false ); + exportSeriesText( xLabelSeq, bIsChartex ); Reference<XPropertySet> xPropSet(xDataSeries, UNO_QUERY_THROW); if( GetProperty( xPropSet, u"AttachedAxisIndex"_ustr) ) @@ -3442,209 +3234,140 @@ void ChartExport::exportSeries_chart( const Reference<chart2::XChartType>& xChar rSeries, getModel() ); if( xOldPropSet.is() ) { - exportShapeProps( xOldPropSet, false ); + exportShapeProps( xOldPropSet, bIsChartex ); } - switch( eChartType ) - { - case chart::TYPEID_BUBBLE: - case chart::TYPEID_HORBAR: - case chart::TYPEID_BAR: - { - pFS->singleElement(FSNS(XML_c, XML_invertIfNegative), XML_val, "0"); - } - break; - case chart::TYPEID_LINE: - { - exportMarker(xOldPropSet); - break; - } - case chart::TYPEID_PIE: - case chart::TYPEID_DOUGHNUT: + if (!bIsChartex) { + switch( eChartType ) { - if( xOldPropSet.is() && GetProperty( xOldPropSet, u"SegmentOffset"_ustr) ) + case chart::TYPEID_BUBBLE: + case chart::TYPEID_HORBAR: + case chart::TYPEID_BAR: { - sal_Int32 nOffset = 0; - mAny >>= nOffset; - pFS->singleElement( FSNS( XML_c, XML_explosion ), - XML_val, OString::number( nOffset ) ); + pFS->singleElement(FSNS(XML_c, XML_invertIfNegative), XML_val, "0"); } break; + case chart::TYPEID_LINE: + { + exportMarker(xOldPropSet); + break; + } + case chart::TYPEID_PIE: + case chart::TYPEID_DOUGHNUT: + { + if( xOldPropSet.is() && GetProperty( xOldPropSet, u"SegmentOffset"_ustr) ) + { + sal_Int32 nOffset = 0; + mAny >>= nOffset; + pFS->singleElement( FSNS( XML_c, XML_explosion ), + XML_val, OString::number( nOffset ) ); + } + break; + } + case chart::TYPEID_SCATTER: + { + exportMarker(xOldPropSet); + break; + } + case chart::TYPEID_RADARLINE: + { + exportMarker(xOldPropSet); + break; + } } - case chart::TYPEID_SCATTER: - { - exportMarker(xOldPropSet); - break; - } - case chart::TYPEID_RADARLINE: - { - exportMarker(xOldPropSet); - break; - } - } - // export data points - exportDataPoints( uno::Reference< beans::XPropertySet >( rSeries, uno::UNO_QUERY ), nSeriesLength, eChartType ); + // export data points + exportDataPoints( uno::Reference< beans::XPropertySet >( rSeries, uno::UNO_QUERY ), nSeriesLength, eChartType ); + } DataLabelsRange aDLblsRange; // export data labels - exportDataLabels(rSeries, nSeriesLength, eChartType, aDLblsRange, false); + exportDataLabels(rSeries, nSeriesLength, eChartType, aDLblsRange, bIsChartex); - exportTrendlines( rSeries ); + if (!bIsChartex) { + exportTrendlines( rSeries ); - if( eChartType != chart::TYPEID_PIE && - eChartType != chart::TYPEID_RADARLINE ) - { - //export error bars here - Reference< XPropertySet > xSeriesPropSet( xSource, uno::UNO_QUERY ); - Reference< XPropertySet > xErrorBarYProps; - xSeriesPropSet->getPropertyValue(u"ErrorBarY"_ustr) >>= xErrorBarYProps; - if(xErrorBarYProps.is()) - exportErrorBar(xErrorBarYProps, true); - if (eChartType != chart::TYPEID_BAR && - eChartType != chart::TYPEID_HORBAR) + if( eChartType != chart::TYPEID_PIE && + eChartType != chart::TYPEID_RADARLINE ) { - Reference< XPropertySet > xErrorBarXProps; - xSeriesPropSet->getPropertyValue(u"ErrorBarX"_ustr) >>= xErrorBarXProps; - if(xErrorBarXProps.is()) - exportErrorBar(xErrorBarXProps, false); + //export error bars here + Reference< XPropertySet > xSeriesPropSet( xSource, uno::UNO_QUERY ); + Reference< XPropertySet > xErrorBarYProps; + xSeriesPropSet->getPropertyValue(u"ErrorBarY"_ustr) >>= xErrorBarYProps; + if(xErrorBarYProps.is()) + exportErrorBar(xErrorBarYProps, true); + if (eChartType != chart::TYPEID_BAR && + eChartType != chart::TYPEID_HORBAR) + { + Reference< XPropertySet > xErrorBarXProps; + xSeriesPropSet->getPropertyValue(u"ErrorBarX"_ustr) >>= xErrorBarXProps; + if(xErrorBarXProps.is()) + exportErrorBar(xErrorBarXProps, false); + } } - } - // export categories - if( eChartType != chart::TYPEID_SCATTER && eChartType != chart::TYPEID_BUBBLE && mxCategoriesValues.is() ) - exportSeriesCategory( mxCategoriesValues ); + // export categories + if( eChartType != chart::TYPEID_SCATTER && eChartType != chart::TYPEID_BUBBLE && mxCategoriesValues.is() ) + exportSeriesCategory( mxCategoriesValues ); - if( (eChartType == chart::TYPEID_SCATTER) - || (eChartType == chart::TYPEID_BUBBLE) ) - { - // export xVal - Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, u"values-x"_ustr ) ); - if( xSequence.is() ) + if( (eChartType == chart::TYPEID_SCATTER) + || (eChartType == chart::TYPEID_BUBBLE) ) { - Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() ); - if( xValues.is() ) - exportSeriesValues( xValues, XML_xVal ); + // export xVal + Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, u"values-x"_ustr ) ); + if( xSequence.is() ) + { + Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() ); + if( xValues.is() ) + exportSeriesValues( xValues, XML_xVal ); + } + else if( mxCategoriesValues.is() ) + exportSeriesCategory( mxCategoriesValues, XML_xVal ); } - else if( mxCategoriesValues.is() ) - exportSeriesCategory( mxCategoriesValues, XML_xVal ); - } - if( eChartType == chart::TYPEID_BUBBLE ) - { - // export yVal - Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, u"values-y"_ustr ) ); - if( xSequence.is() ) + if( eChartType == chart::TYPEID_BUBBLE ) { - Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() ); - if( xValues.is() ) - exportSeriesValues( xValues, XML_yVal ); + // export yVal + Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, u"values-y"_ustr ) ); + if( xSequence.is() ) + { + Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() ); + if( xValues.is() ) + exportSeriesValues( xValues, XML_yVal ); + } } - } - // export values - if( xValuesSeq.is() ) - { - sal_Int32 nYValueType = XML_val; - if( eChartType == chart::TYPEID_SCATTER ) - nYValueType = XML_yVal; - else if( eChartType == chart::TYPEID_BUBBLE ) - nYValueType = XML_bubbleSize; - exportSeriesValues( xValuesSeq, nYValueType ); - } - - if( eChartType == chart::TYPEID_SCATTER - || eChartType == chart::TYPEID_LINE ) - exportSmooth(); - - // tdf103988: "corrupted" files with Bubble chart opening in MSO - if( eChartType == chart::TYPEID_BUBBLE ) - pFS->singleElement(FSNS(XML_c, XML_bubble3D), XML_val, "0"); - - if (!aDLblsRange.empty()) - writeDataLabelsRange(pFS, GetFB(), aDLblsRange); - - pFS->endElement( FSNS( XML_c, XML_ser ) ); - } - } - } -} - -void ChartExport::exportSeries_chartex( const Reference<chart2::XChartType>& xChartType, - const Sequence<Reference<chart2::XDataSeries> >& rSeriesSeq, - const char* sTypeName) -{ - OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel(); - OUString aChartType( xChartType->getChartType()); - sal_Int32 eChartType = lcl_getChartType( aChartType ); - - sal_Int32 nSeriesCnt = 0; - for( const auto& rSeries : rSeriesSeq ) - { - // export series - Reference< chart2::data::XDataSource > xSource( rSeries, uno::UNO_QUERY ); - if( xSource.is()) - { - FSHelperPtr pFS = GetFS(); - pFS->startElement(FSNS(XML_cx, XML_series), XML_layoutId, sTypeName); - - Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt( - xSource->getDataSequences()); - - // search for main sequence and create a series element - sal_Int32 nMainSequenceIndex = -1; - sal_Int32 nSeriesLength = 0; - Reference< chart2::data::XDataSequence > xLabelSeq; - sal_Int32 nSeqIdx=0; - for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx ) - { - Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() ); - if( nMainSequenceIndex==-1 ) - { - Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY ); - OUString aRole; - if( xSeqProp.is()) - xSeqProp->getPropertyValue(u"Role"_ustr) >>= aRole; - // "main" sequence - if( aRole == aLabelRole ) + // export values + if( xValuesSeq.is() ) { - xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel()); - nMainSequenceIndex = nSeqIdx; + sal_Int32 nYValueType = XML_val; + if( eChartType == chart::TYPEID_SCATTER ) + nYValueType = XML_yVal; + else if( eChartType == chart::TYPEID_BUBBLE ) + nYValueType = XML_bubbleSize; + exportSeriesValues( xValuesSeq, nYValueType ); } - } - sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0)); - if( nSeriesLength < nSequenceLength ) - nSeriesLength = nSequenceLength; - } - // export label - if( xLabelSeq.is() ) - exportSeriesText( xLabelSeq, true ); + if( eChartType == chart::TYPEID_SCATTER + || eChartType == chart::TYPEID_LINE ) + exportSmooth(); - // export shape properties - Reference< XPropertySet > xOldPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet( - rSeries, getModel() ); - if( xOldPropSet.is() ) - { - exportShapeProps( xOldPropSet, true ); - } + // tdf103988: "corrupted" files with Bubble chart opening in MSO + if( eChartType == chart::TYPEID_BUBBLE ) + pFS->singleElement(FSNS(XML_c, XML_bubble3D), XML_val, "0"); - DataLabelsRange aDLblsRange; - // export data labels - exportDataLabels(rSeries, nSeriesLength, eChartType, aDLblsRange, true); + if (!aDLblsRange.empty()) + writeDataLabelsRange(pFS, GetFB(), aDLblsRange); - // dataId links to the correct data set in the <cx:chartData>. See - // DATA_ID_COMMENT - pFS->singleElement(FSNS(XML_cx, XML_dataId), XML_val, - OString::number(nSeriesCnt++)); - - // layoutPr - - // axisId - - // extLst + pFS->endElement( FSNS( XML_c, XML_ser ) ); + } else { + // chartex - pFS->endElement(FSNS(XML_cx, XML_series)); + // Align the data id here with that in exportData(). + // See DATA_ID_COMMENT + pFS->singleElement(FSNS(XML_cx, XML_dataId), XML_val, "0"); + } + } } } } @@ -3997,8 +3720,7 @@ void ChartExport::InitPlotArea( ) if( mbHasCategoryLabels && mxNewDiagram.is()) { - Reference< chart2::data::XLabeledDataSequence > xCategories( - lcl_getCategories( mxNewDiagram, &mbHasDateCategories ) ); + Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram, mbHasDateCategories ) ); if( xCategories.is() ) { mxCategoriesValues.set( xCategories->getValues() ); diff --git a/test/source/xmltesttools.cxx b/test/source/xmltesttools.cxx index b2290c937483..84541419520d 100644 --- a/test/source/xmltesttools.cxx +++ b/test/source/xmltesttools.cxx @@ -88,11 +88,6 @@ void XmlTestTools::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) } OUString XmlTestTools::getXPath(const xmlDocUniquePtr& pXmlDoc, const char* pXPath, const char* pAttribute) -{ - return getXPath(pXmlDoc, pXPath, 1, 0, pAttribute); -} - -OUString XmlTestTools::getXPath(const xmlDocUniquePtr& pXmlDoc, const char*pXPath, int nNumNodes, int nPathIdx, const char* pAttribute) { CPPUNIT_ASSERT(pXmlDoc); xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, pXPath); @@ -101,10 +96,10 @@ OUString XmlTestTools::getXPath(const xmlDocUniquePtr& pXmlDoc, const char*pXPat xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval; CPPUNIT_ASSERT_MESSAGE(OString(docAndXPath + "' not found").getStr(), pXmlNodes); CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(docAndXPath + "' number of nodes is incorrect").getStr(), - nNumNodes, xmlXPathNodeSetGetLength(pXmlNodes)); + 1, xmlXPathNodeSetGetLength(pXmlNodes)); CPPUNIT_ASSERT(pAttribute); CPPUNIT_ASSERT(pAttribute[0]); - xmlNodePtr pXmlNode = pXmlNodes->nodeTab[nPathIdx]; + xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0]; xmlChar * prop = xmlGetProp(pXmlNode, BAD_CAST(pAttribute)); OString sAttAbsent = docAndXPath + "' no attribute '" + pAttribute + "' exist"; CPPUNIT_ASSERT_MESSAGE(sAttAbsent.getStr(), prop); @@ -182,16 +177,6 @@ void XmlTestTools::assertXPathInsensitive(const xmlDocUniquePtr& pXmlDoc, const aExpectedValue, aValue); } -// Verify the given path and attribute, where the expected number of nodes with -// the given path is nNumNodes and the desired node index is nPathIdx. -void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const char* - pXPath, int nNumNodes, int nPathIdx, const char* pAttribute, std::u16string_view rExpectedValue) -{ - OUString aValue = getXPath(pXmlDoc, pXPath, nNumNodes, nPathIdx, pAttribute); - CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, attribute '" + pAttribute + "' of '" + pXPath + "' incorrect value.").getStr(), - rExpectedValue, std::u16string_view(aValue)); -} - void XmlTestTools::assertXPathDoubleValue(const xmlDocUniquePtr& pXmlDoc, const char* pXPath, const char* pAttribute, double expectedValue, double delta) { OUString aValue = getXPath(pXmlDoc, pXPath, pAttribute);
