chart2/qa/extras/chart2export.cxx                  |   41 +++++++++++++++++++++
 chart2/qa/extras/data/xlsx/invertIfNeg_bar.xlsx    |binary
 chart2/qa/extras/data/xlsx/invertIfNeg_bubble.xlsx |binary
 chart2/source/inc/DataSeriesProperties.hxx         |    3 +
 chart2/source/model/main/DataPointProperties.cxx   |    7 +++
 chart2/source/model/main/DataPointProperties.hxx   |    1 
 chart2/source/model/main/DataSeriesProperties.cxx  |    7 +++
 chart2/source/view/charttypes/BarChart.cxx         |   21 ++++++++++
 chart2/source/view/charttypes/BubbleChart.cxx      |   27 ++++++++++++-
 oox/source/drawingml/chart/seriesconverter.cxx     |    7 +++
 oox/source/token/properties.txt                    |    1 
 11 files changed, 112 insertions(+), 3 deletions(-)

New commits:
commit 4c45ce3493e9ee842fff42228913cc11b173ca93
Author:     Kurt Nordback <kurt.nordb...@protonmail.com>
AuthorDate: Wed Aug 14 15:44:24 2024 -0600
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Tue Aug 27 09:21:35 2024 +0200

    tdf#90733 - support invertIfNegative for bar and bubble chart
    
    Extend the existing initial support for the OOXML invertIfNegative tag to 
pass
    the data down into bar and bubble chart rendering. Also add corresponding 
unit
    tests. This does not include a UI control to select/deselect the invert-if-
    negative option, nor support for export of the flag to OOXML, nor any 
support
    in ODF.
    
    Change-Id: I45b24b816edc379c9b431e86269dd5ff37977b89
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171879
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/chart2/qa/extras/chart2export.cxx 
b/chart2/qa/extras/chart2export.cxx
index 4335ee9ff887..9a81cc0d052a 100644
--- a/chart2/qa/extras/chart2export.cxx
+++ b/chart2/qa/extras/chart2export.cxx
@@ -1321,6 +1321,47 @@ CPPUNIT_TEST_FIXTURE(Chart2ExportTest, 
testLabelStringODS)
     CPPUNIT_ASSERT_EQUAL(u"\"LabelName\""_ustr, aLabelString);
 }
 
+
+CPPUNIT_TEST_FIXTURE(Chart2ExportTest, testInvertNegative)
+{
+    // Bar chart
+    {
+        loadFromFile(u"xlsx/invertIfNeg_bar.xlsx");
+        // make sure the import was successful
+        uno::Reference< chart2::XChartDocument > xChartDoc = 
getChartDocFromSheet( 0, mxComponent );
+        CPPUNIT_ASSERT(xChartDoc.is());
+
+        Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( 
xChartDoc, 0 );
+        CPPUNIT_ASSERT( xDataSeries.is() );
+
+        Reference< beans::XPropertySet > xPropSet( xDataSeries, 
UNO_QUERY_THROW );
+
+        bool bInvertNeg;
+        CPPUNIT_ASSERT(
+            xPropSet->getPropertyValue(u"InvertNegative"_ustr) >>= bInvertNeg);
+        CPPUNIT_ASSERT_EQUAL(true, bInvertNeg);
+    }
+
+    // Bubble chart
+    {
+        loadFromFile(u"xlsx/invertIfNeg_bubble.xlsx");
+        // make sure the import was successful
+        uno::Reference< chart2::XChartDocument > xChartDoc = 
getChartDocFromSheet( 0, mxComponent );
+        CPPUNIT_ASSERT(xChartDoc.is());
+
+        Reference< chart2::XDataSeries > xDataSeries = getDataSeriesFromDoc( 
xChartDoc, 0 );
+        CPPUNIT_ASSERT( xDataSeries.is() );
+
+        Reference< beans::XPropertySet > xPropSet( xDataSeries, 
UNO_QUERY_THROW );
+
+        bool bInvertNeg;
+        CPPUNIT_ASSERT(
+            xPropSet->getPropertyValue(u"InvertNegative"_ustr) >>= bInvertNeg);
+        CPPUNIT_ASSERT_EQUAL(true, bInvertNeg);
+    }
+}
+
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/qa/extras/data/xlsx/invertIfNeg_bar.xlsx 
b/chart2/qa/extras/data/xlsx/invertIfNeg_bar.xlsx
new file mode 100644
index 000000000000..97a83b43dc2f
Binary files /dev/null and b/chart2/qa/extras/data/xlsx/invertIfNeg_bar.xlsx 
differ
diff --git a/chart2/qa/extras/data/xlsx/invertIfNeg_bubble.xlsx 
b/chart2/qa/extras/data/xlsx/invertIfNeg_bubble.xlsx
new file mode 100644
index 000000000000..27ae097e2eba
Binary files /dev/null and b/chart2/qa/extras/data/xlsx/invertIfNeg_bubble.xlsx 
differ
diff --git a/chart2/source/inc/DataSeriesProperties.hxx 
b/chart2/source/inc/DataSeriesProperties.hxx
index 7d36721ef066..d0c19d07bf23 100644
--- a/chart2/source/inc/DataSeriesProperties.hxx
+++ b/chart2/source/inc/DataSeriesProperties.hxx
@@ -35,7 +35,8 @@ namespace chart::DataSeriesProperties
         PROP_DATASERIES_ATTACHED_AXIS_INDEX,
         PROP_DATASERIES_SHOW_LEGEND_ENTRY,
         PROP_DATASERIES_DELETED_LEGEND_ENTRIES,
-        PROP_DATASERIES_SHOW_CUSTOM_LEADERLINES
+        PROP_DATASERIES_SHOW_CUSTOM_LEADERLINES,
+        PROP_DATASERIES_INVERT_NEGATIVE
     };
 
     void AddPropertiesToVector(
diff --git a/chart2/source/model/main/DataPointProperties.cxx 
b/chart2/source/model/main/DataPointProperties.cxx
index d86128b7593e..53f88600214f 100644
--- a/chart2/source/model/main/DataPointProperties.cxx
+++ b/chart2/source/model/main/DataPointProperties.cxx
@@ -340,6 +340,12 @@ void DataPointProperties::AddPropertiesToVector(
                   beans::PropertyAttribute::BOUND
                   | beans::PropertyAttribute::MAYBEDEFAULT );
 
+    rOutProperties.emplace_back( "InvertNegative",
+                  PROP_DATAPOINT_INVERT_NEGATIVE,
+                  cppu::UnoType<bool>::get(),
+                  beans::PropertyAttribute::BOUND
+                  | beans::PropertyAttribute::MAYBEDEFAULT );
+
     // statistics
     rOutProperties.emplace_back( CHART_UNONAME_ERRORBAR_X,
                   PROP_DATAPOINT_ERROR_BAR_X,
@@ -513,6 +519,7 @@ void DataPointProperties::AddDefaultsToMap(
     PropertyHelper::setPropertyValueDefault( rOutMap, 
PROP_DATAPOINT_PERCENT_DIAGONAL, sal_Int16(0) );
 
     PropertyHelper::setPropertyValueDefault( rOutMap, 
PROP_DATAPOINT_TEXT_ROTATION, 0.0 );
+    PropertyHelper::setPropertyValueDefault( rOutMap, 
PROP_DATAPOINT_INVERT_NEGATIVE, false );
 
     PropertyHelper::setPropertyValueDefault(rOutMap, 
PROP_DATAPOINT_LINK_NUMBERFORMAT_TO_SOURCE, true);
 
diff --git a/chart2/source/model/main/DataPointProperties.hxx 
b/chart2/source/model/main/DataPointProperties.hxx
index 1689322148d8..fe1969bc5f15 100644
--- a/chart2/source/model/main/DataPointProperties.hxx
+++ b/chart2/source/model/main/DataPointProperties.hxx
@@ -69,6 +69,7 @@ namespace DataPointProperties
         PROP_DATAPOINT_LABEL_PLACEMENT,
         PROP_DATAPOINT_REFERENCE_DIAGRAM_SIZE,
         PROP_DATAPOINT_TEXT_ROTATION,
+        PROP_DATAPOINT_INVERT_NEGATIVE,
 
         // statistics
         PROP_DATAPOINT_ERROR_BAR_X,
diff --git a/chart2/source/model/main/DataSeriesProperties.cxx 
b/chart2/source/model/main/DataSeriesProperties.cxx
index e6d40feb5ab6..c558b3820cab 100644
--- a/chart2/source/model/main/DataSeriesProperties.cxx
+++ b/chart2/source/model/main/DataSeriesProperties.cxx
@@ -75,6 +75,12 @@ void DataSeriesProperties::AddPropertiesToVector(
                   beans::PropertyAttribute::BOUND
                   | beans::PropertyAttribute::MAYBEDEFAULT );
 
+    rOutProperties.emplace_back( "InvertNegative",
+                  PROP_DATASERIES_INVERT_NEGATIVE,
+                  cppu::UnoType<sal_Bool>::get(),
+                  beans::PropertyAttribute::BOUND
+                  | beans::PropertyAttribute::MAYBEDEFAULT );
+
     // add properties of service DataPointProperties
     DataPointProperties::AddPropertiesToVector( rOutProperties );
 }
@@ -87,6 +93,7 @@ void DataSeriesProperties::AddDefaultsToMap(
     PropertyHelper::setPropertyValueDefault( rOutMap, 
PROP_DATASERIES_ATTACHED_AXIS_INDEX, sal_Int32(0) );
     PropertyHelper::setPropertyValueDefault( rOutMap, 
PROP_DATASERIES_SHOW_LEGEND_ENTRY, true );
     PropertyHelper::setPropertyValueDefault( rOutMap, 
PROP_DATASERIES_SHOW_CUSTOM_LEADERLINES, true );
+    PropertyHelper::setPropertyValueDefault( rOutMap, 
PROP_DATASERIES_INVERT_NEGATIVE, false );
 
     // PROP_DATASERIES_ATTRIBUTED_DATA_POINTS has no default
 
diff --git a/chart2/source/view/charttypes/BarChart.cxx 
b/chart2/source/view/charttypes/BarChart.cxx
index 8babf67271fd..38a497707d22 100644
--- a/chart2/source/view/charttypes/BarChart.cxx
+++ b/chart2/source/view/charttypes/BarChart.cxx
@@ -708,6 +708,27 @@ void BarChart::doXSlot(
         if( std::isnan( fLogicBarHeight )) //no value at this category
             continue;
 
+        // Handle "invert negative"
+        {
+            bool bInvertNeg(false);
+            uno::Reference< beans::XPropertySet > xPointProperties = 
pSeries->getPropertiesOfPoint(nPointIndex);
+
+            // check point properties, and if none then series properties
+            try {
+                xPointProperties->getPropertyValue(u"InvertNegative"_ustr) >>= 
bInvertNeg;
+            } catch (const uno::Exception&)
+            {
+                uno::Reference< beans::XPropertySet > xSeriesProperties =
+                    pSeries->getPropertiesOfSeries();
+                try {
+                    
xSeriesProperties->getPropertyValue(u"InvertNegative"_ustr) >>= bInvertNeg;
+                } catch (const uno::Exception&)
+                {}
+            }
+
+            if (bInvertNeg) fLogicBarHeight = fabs(fLogicBarHeight);
+        }
+
         double fLogicValueForLabeDisplay = fLogicBarHeight;
         fLogicBarHeight-=fBaseValue;
 
diff --git a/chart2/source/view/charttypes/BubbleChart.cxx 
b/chart2/source/view/charttypes/BubbleChart.cxx
index fb7b3fe6f33d..88f39b3a5235 100644
--- a/chart2/source/view/charttypes/BubbleChart.cxx
+++ b/chart2/source/view/charttypes/BubbleChart.cxx
@@ -217,8 +217,31 @@ void BubbleChart::createShapes()
                     double fLogicY = pSeries->getYValue(nIndex);
                     double fBubbleSize = pSeries->getBubble_Size( nIndex );
 
-                    if( fBubbleSize<0.0 )
-                        continue;
+                    bool bInvertNeg(false);
+                    uno::Reference< beans::XPropertySet > xPointProperties =
+                        pSeries->getPropertiesOfPoint(nIndex);
+
+                    // check point properties, and if none then series
+                    // properties
+                    try {
+                        
xPointProperties->getPropertyValue(u"InvertNegative"_ustr) >>= bInvertNeg;
+                    } catch (const uno::Exception&)
+                    {
+                        uno::Reference< beans::XPropertySet > 
xSeriesProperties =
+                            pSeries->getPropertiesOfSeries();
+                        try {
+                            
xSeriesProperties->getPropertyValue(u"InvertNegative"_ustr) >>= bInvertNeg;
+                        } catch (const uno::Exception&)
+                        {}
+                    }
+
+                    if( fBubbleSize<0.0 ) {
+                        if (bInvertNeg) {
+                            fBubbleSize = -fBubbleSize;
+                        } else {
+                            continue;
+                        }
+                    }
 
                     if( fBubbleSize == 0.0 || std::isnan(fBubbleSize) )
                         continue;
diff --git a/oox/source/drawingml/chart/seriesconverter.cxx 
b/oox/source/drawingml/chart/seriesconverter.cxx
index b3c8b51c16b9..efa7f303662e 100644
--- a/oox/source/drawingml/chart/seriesconverter.cxx
+++ b/oox/source/drawingml/chart/seriesconverter.cxx
@@ -765,6 +765,11 @@ void DataPointConverter::convertFromModel( const 
Reference< XDataSeries >& rxDat
         if( mrModel.monExplosion.has_value() && mrModel.monExplosion.value() 
!= rSeries.mnExplosion )
             rTypeGroup.convertPieExplosion( aPropSet, 
mrModel.monExplosion.value() );
 
+        // data point invert negative
+        if( mrModel.mbInvertNeg != rSeries.mbInvertNeg ) {
+            aPropSet.setProperty( PROP_InvertNegative, mrModel.mbInvertNeg);
+        }
+
         // point formatting
         if( mrModel.mxShapeProp.is() )
         {
@@ -873,6 +878,8 @@ Reference< XDataSeries > SeriesConverter::createDataSeries( 
const TypeGroupConve
     rTypeGroup.convertBarGeometry( aSeriesProp, mrModel.monShape.value_or( 
rTypeGroup.getModel().mnShape ) );
     // pie explosion (restricted to [0%,100%] in Chart2)
     rTypeGroup.convertPieExplosion( aSeriesProp, mrModel.mnExplosion );
+    // invert if negative
+    aSeriesProp.setProperty(PROP_InvertNegative, mrModel.mbInvertNeg);
 
     // series formatting
     ObjectFormatter& rFormatter = getFormatter();
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index f68726957df9..6140d192b55d 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -290,6 +290,7 @@ InputMessage
 InputTitle
 InterceptValue
 InvalidUrl
+InvertNegative
 IsActive
 IsAdjustHeightEnabled
 IsCaseSensitive

Reply via email to