Rebased ref, commits from common ancestor:
commit db7383852b001d5bb07435b2242068d964a31f17
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Mon Feb 28 15:35:48 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Mon Feb 28 15:35:48 2022 +0900

    sc: support sparkline bar colors, add markers to sparkline lines
    
    Change-Id: I705a7f57cc4d6544ecb35a5f93c18a27056b9944

diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 358688c15d90..354bd16804f9 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -2316,33 +2316,121 @@ void ScOutputData::DrawChangeTrack()
 namespace
 {
 
+struct SparklineMarker
+{
+    basegfx::B2DPolygon maPolygon;
+    Color maColor;
+};
+
+void createMarker(std::vector<SparklineMarker> & rMarkers, double x, double y, 
Color const & rColor)
+{
+    auto & rMarker = rMarkers.emplace_back();
+    basegfx::B2DRectangle aRectangle(x - 2, y - 2, x + 2, y + 2);
+    rMarker.maPolygon = basegfx::utils::createPolygonFromRect(aRectangle);
+    rMarker.maColor = rColor;
+}
+
 void drawLine(vcl::RenderContext& rRenderContext, tools::Rectangle const & 
rRectangle,
-                std::vector<double> const & rValues, double nMin, double nMax)
+                std::vector<double> const & rValues, double nMin, double nMax,
+                std::shared_ptr<sc::SparklineGroup> const & pSparklineGroup)
 {
     basegfx::B2DPolygon aPolygon;
     double numebrOfSteps = rValues.size() - 1;
     double xStep = 0;
     double nDelta = nMax - nMin;
 
-    for (double aValue : rValues)
+    std::vector<SparklineMarker> aMarkers;
+    sal_Int64 nValueIndex = 0;
+    sal_Int64 nValuesSize = rValues.size();
+
+    for (double nValue : rValues)
     {
-        double nP = (aValue - nMin) / nDelta;
+        double nP = (nValue - nMin) / nDelta;
         double x = rRectangle.GetWidth() * (xStep / numebrOfSteps);
         double y = rRectangle.GetHeight() - rRectangle.GetHeight() * nP;
 
         aPolygon.append({ x, y } );
+
+        if (pSparklineGroup->m_bFirst && nValueIndex == 0)
+        {
+            createMarker(aMarkers, x, y, pSparklineGroup->m_aColorFirst);
+        }
+        else if (pSparklineGroup->m_bLast && nValueIndex == (nValuesSize - 1))
+        {
+            createMarker(aMarkers, x, y, pSparklineGroup->m_aColorLast);
+        }
+        else if (pSparklineGroup->m_bHigh && nValue == nMax)
+        {
+            createMarker(aMarkers, x, y, pSparklineGroup->m_aColorHigh);
+        }
+        else if (pSparklineGroup->m_bLow && nValue == nMin)
+        {
+            createMarker(aMarkers, x, y, pSparklineGroup->m_aColorLow);
+        }
+        else if (pSparklineGroup->m_bNegative && nValue < 0.0)
+        {
+            createMarker(aMarkers, x, y, pSparklineGroup->m_aColorNegative);
+        }
+
         xStep++;
+        nValueIndex++;
     }
 
     basegfx::B2DHomMatrix aMatrix;
     aMatrix.translate(rRectangle.Left(), rRectangle.Top());
     aPolygon.transform(aMatrix);
 
+    rRenderContext.SetLineColor(pSparklineGroup->m_aColorSeries);
     rRenderContext.DrawPolyLine(aPolygon);
+
+    for (auto const & rMarker : aMarkers)
+    {
+        rRenderContext.SetLineColor(rMarker.maColor);
+        rRenderContext.SetFillColor(rMarker.maColor);
+        aPolygon = rMarker.maPolygon;
+        aPolygon.transform(aMatrix);
+        rRenderContext.DrawPolygon(aPolygon);
+    }
+}
+
+void setFillAndLineColor(vcl::RenderContext& rRenderContext, 
std::shared_ptr<sc::SparklineGroup> const & pSparklineGroup,
+                         double nValue, sal_Int64 nValueIndex, sal_Int64 
nValuesSize, double nMin, double nMax)
+{
+    if (pSparklineGroup->m_bFirst && nValueIndex == 0)
+    {
+        rRenderContext.SetLineColor(pSparklineGroup->m_aColorFirst);
+        rRenderContext.SetFillColor(pSparklineGroup->m_aColorFirst);
+    }
+    else if (pSparklineGroup->m_bLast && nValueIndex == (nValuesSize - 1))
+    {
+        rRenderContext.SetLineColor(pSparklineGroup->m_aColorLast);
+        rRenderContext.SetFillColor(pSparklineGroup->m_aColorLast);
+    }
+    else if (pSparklineGroup->m_bHigh && nValue == nMax)
+    {
+        rRenderContext.SetLineColor(pSparklineGroup->m_aColorHigh);
+        rRenderContext.SetFillColor(pSparklineGroup->m_aColorHigh);
+    }
+    else if (pSparklineGroup->m_bLow && nValue == nMin)
+    {
+        rRenderContext.SetLineColor(pSparklineGroup->m_aColorLow);
+        rRenderContext.SetFillColor(pSparklineGroup->m_aColorLow);
+    }
+    else if (pSparklineGroup->m_bNegative && nValue < 0.0)
+    {
+        rRenderContext.SetLineColor(pSparklineGroup->m_aColorNegative);
+        rRenderContext.SetFillColor(pSparklineGroup->m_aColorNegative);
+    }
+    else
+    {
+        rRenderContext.SetLineColor(pSparklineGroup->m_aColorSeries);
+        rRenderContext.SetFillColor(pSparklineGroup->m_aColorSeries);
+    }
 }
 
 void drawColumn(vcl::RenderContext& rRenderContext, tools::Rectangle const & 
rRectangle,
-                std::vector<double> const & rValues, double nMin, double nMax)
+                std::vector<double> const & rValues, double nMin, double nMax,
+                std::shared_ptr<sc::SparklineGroup> const & pSparklineGroup)
 {
     basegfx::B2DPolygon aPolygon;
 
@@ -2359,11 +2447,15 @@ void drawColumn(vcl::RenderContext& rRenderContext, 
tools::Rectangle const & rRe
     else
         nZeroPosition = rRectangle.GetHeight();
 
-    for (double aValue : rValues)
+    sal_Int64 nValueIndex = 0;
+
+    for (double nValue : rValues)
     {
-        if (aValue != 0.0)
+        if (nValue != 0.0)
         {
-            double nP = (aValue - nMin) / nDelta;
+            setFillAndLineColor(rRenderContext, pSparklineGroup, nValue, 
nValueIndex, sal_Int64(rValues.size()), nMax, nMin);
+
+            double nP = (nValue - nMin) / nDelta;
             double x = rRectangle.GetWidth() * (xStep / numberOfSteps);
             double y = rRectangle.GetHeight() - rRectangle.GetHeight() * nP;
 
@@ -2376,6 +2468,7 @@ void drawColumn(vcl::RenderContext& rRenderContext, 
tools::Rectangle const & rRe
             rRenderContext.DrawPolygon(aPolygon);
         }
         xStep++;
+        nValueIndex++;
     }
 }
 
@@ -2391,9 +2484,6 @@ void drawSparkline(sc::Sparkline* pSparkline, 
vcl::RenderContext& rRenderContext
 
     rRenderContext.SetAntialiasing(AntialiasingFlags::Enable);
 
-    rRenderContext.SetLineColor(pSparklineGroup->m_aColorSeries);
-    rRenderContext.SetFillColor(pSparklineGroup->m_aColorSeries);
-
     ScRange aRange = rRangeList[0];
 
     std::vector<double> aValues;
@@ -2434,7 +2524,7 @@ void drawSparkline(sc::Sparkline* pSparkline, 
vcl::RenderContext& rRenderContext
 
     if (pSparklineGroup->m_eType == sc::SparklineType::Column)
     {
-        drawColumn(rRenderContext, rRectangle, aValues, nMin, nMax);
+        drawColumn(rRenderContext, rRectangle, aValues, nMin, nMax, 
pSparklineGroup);
     }
     else if (pSparklineGroup->m_eType == sc::SparklineType::Stacked)
     {
@@ -2444,11 +2534,11 @@ void drawSparkline(sc::Sparkline* pSparkline, 
vcl::RenderContext& rRenderContext
             if (rValue != 0.0)
                 rValue = rValue > 0.0 ? 1.0 : -1.0;
         }
-        drawColumn(rRenderContext, rRectangle, aValues, -1, 1);
+        drawColumn(rRenderContext, rRectangle, aValues, -1, 1, 
pSparklineGroup);
     }
     else if (pSparklineGroup->m_eType == sc::SparklineType::Line)
     {
-        drawLine(rRenderContext, rRectangle, aValues, nMin, nMax);
+        drawLine(rRenderContext, rRectangle, aValues, nMin, nMax, 
pSparklineGroup);
     }
 }
 } // end anonymous namespace
commit 551c634a7c3f588ad946276720be597e4ffb86be
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Thu Feb 24 18:04:37 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sun Feb 27 20:58:56 2022 +0900

    sc: first simple test for Sparklines
    
    Change-Id: I513571de398be419074d54c5861374effae07709

diff --git a/sc/CppunitTest_sc_sparkline_test.mk 
b/sc/CppunitTest_sc_sparkline_test.mk
new file mode 100644
index 000000000000..edf7a3cac7da
--- /dev/null
+++ b/sc/CppunitTest_sc_sparkline_test.mk
@@ -0,0 +1,60 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sc_sparkline_test))
+
+$(eval $(call gb_CppunitTest_use_common_precompiled_header,sc_sparkline_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sc_sparkline_test, \
+    sc/qa/extras/SparklineTest \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sc_sparkline_test, \
+    basegfx \
+    comphelper \
+    cppu \
+    cppuhelper \
+    sal \
+    salhelper \
+    sax \
+    sc \
+    scqahelper \
+    sfx \
+    subsequenttest \
+    test \
+    tl \
+    unotest \
+    vcl \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sc_sparkline_test,\
+    -I$(SRCDIR)/sc/source/ui/inc \
+    -I$(SRCDIR)/sc/inc \
+    $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,sc_sparkline_test,\
+    offapi \
+    udkapi \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sc_sparkline_test))
+
+$(eval $(call gb_CppunitTest_use_ure,sc_sparkline_test))
+$(eval $(call gb_CppunitTest_use_vcl,sc_sparkline_test))
+
+$(eval $(call gb_CppunitTest_use_rdb,sc_sparkline_test,services))
+
+$(eval $(call gb_CppunitTest_use_components,sc_sparkline_test))
+
+$(eval $(call gb_CppunitTest_use_configuration,sc_sparkline_test))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index c37b37dd2a14..d877627b20e2 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -204,6 +204,7 @@ $(eval $(call gb_Module_add_subsequentcheck_targets,sc,\
        CppunitTest_sc_sheetlinkobj \
        CppunitTest_sc_sheetlinksobj \
        CppunitTest_sc_sortdescriptorbaseobj \
+       CppunitTest_sc_sparkline_test \
        CppunitTest_sc_spreadsheetsettings \
        CppunitTest_sc_spreadsheetsettingsobj \
        CppunitTest_sc_styleobj \
diff --git a/sc/qa/extras/SparklineTest.cxx b/sc/qa/extras/SparklineTest.cxx
new file mode 100644
index 000000000000..122a6b23f5be
--- /dev/null
+++ b/sc/qa/extras/SparklineTest.cxx
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <test/calc_unoapi_test.hxx>
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <docsh.hxx>
+#include <Sparkline.hxx>
+
+using namespace css;
+
+namespace sc_apitest
+{
+class SparklineTest : public CalcUnoApiTest
+{
+    uno::Reference<lang::XComponent> mxComponent;
+
+public:
+    SparklineTest();
+
+    void testSparklines();
+
+    CPPUNIT_TEST_SUITE(SparklineTest);
+    CPPUNIT_TEST(testSparklines);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+SparklineTest::SparklineTest()
+    : CalcUnoApiTest("sc/qa/extras/testdocuments")
+{
+}
+
+void SparklineTest::testSparklines()
+{
+    OUString aFileURL;
+    createFileURL(u"Sparklines.xlsx", aFileURL);
+    mxComponent = loadFromDesktop(aFileURL);
+
+    SfxObjectShell* pFoundShell = 
SfxObjectShell::GetShellFromComponent(mxComponent);
+    CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
+    ScDocShellRef xDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
+    CPPUNIT_ASSERT(xDocSh);
+
+    ScDocument& rDocument = xDocSh->GetDocument();
+    // Sparkline at Sheet1:A2
+    {
+        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 1, 
0)); // A2
+        CPPUNIT_ASSERT(pSparkline);
+        auto pSparklineGroup = pSparkline->getSparklineGroup();
+        CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, 
pSparklineGroup->m_eType);
+
+        CPPUNIT_ASSERT_EQUAL(Color(0x376092), pSparklineGroup->m_aColorSeries);
+        CPPUNIT_ASSERT_EQUAL(Color(0x00b050), 
pSparklineGroup->m_aColorNegative);
+        CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorAxis);
+        CPPUNIT_ASSERT_EQUAL(Color(0x000000), 
pSparklineGroup->m_aColorMarkers);
+        CPPUNIT_ASSERT_EQUAL(Color(0x7030a0), pSparklineGroup->m_aColorFirst);
+        CPPUNIT_ASSERT_EQUAL(Color(0xff0000), pSparklineGroup->m_aColorLast);
+        CPPUNIT_ASSERT_EQUAL(Color(0x92d050), pSparklineGroup->m_aColorHigh);
+        CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), pSparklineGroup->m_aColorLow);
+
+        CPPUNIT_ASSERT_EQUAL(1.0, pSparklineGroup->m_fLineWeight);
+        CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDateAxis);
+        CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellAs::Gap, 
pSparklineGroup->m_eDisplayEmptyCellsAs);
+
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bMarkers);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bHigh);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLow);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bFirst);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLast);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bNegative);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bDisplayXAxis);
+        CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayHidden);
+        CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bRightToLeft);
+
+        CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMax));
+        CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMin));
+    }
+    // Sparkline at Sheet1:A3
+    {
+        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 2, 
0)); // A3
+        CPPUNIT_ASSERT(pSparkline);
+        auto pSparklineGroup = pSparkline->getSparklineGroup();
+        CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, 
pSparklineGroup->m_eType);
+
+        CPPUNIT_ASSERT_EQUAL(Color(0x376092), pSparklineGroup->m_aColorSeries);
+        CPPUNIT_ASSERT_EQUAL(Color(0xff0000), 
pSparklineGroup->m_aColorNegative);
+        CPPUNIT_ASSERT_EQUAL(Color(0x000000), pSparklineGroup->m_aColorAxis);
+        CPPUNIT_ASSERT_EQUAL(Color(0xd00000), 
pSparklineGroup->m_aColorMarkers);
+        CPPUNIT_ASSERT_EQUAL(Color(0x92d050), pSparklineGroup->m_aColorFirst);
+        CPPUNIT_ASSERT_EQUAL(Color(0x00b0f0), pSparklineGroup->m_aColorLast);
+        CPPUNIT_ASSERT_EQUAL(Color(0x7030a0), pSparklineGroup->m_aColorHigh);
+        CPPUNIT_ASSERT_EQUAL(Color(0xffc000), pSparklineGroup->m_aColorLow);
+
+        CPPUNIT_ASSERT_EQUAL(0.75, pSparklineGroup->m_fLineWeight);
+        CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDateAxis);
+        CPPUNIT_ASSERT_EQUAL(sc::DisplayEmptyCellAs::Gap, 
pSparklineGroup->m_eDisplayEmptyCellsAs);
+
+        CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bMarkers);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bHigh);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLow);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bFirst);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bLast);
+        CPPUNIT_ASSERT_EQUAL(true, pSparklineGroup->m_bNegative);
+        CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayXAxis);
+        CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bDisplayHidden);
+        CPPUNIT_ASSERT_EQUAL(false, pSparklineGroup->m_bRightToLeft);
+
+        CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMax));
+        CPPUNIT_ASSERT_EQUAL(false, bool(pSparklineGroup->m_aManualMin));
+    }
+    // Sparkline at Sheet2:B1
+    {
+        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 0, 
1)); //B1
+        CPPUNIT_ASSERT(pSparkline);
+        auto pSparklineGroup = pSparkline->getSparklineGroup();
+        CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Column, 
pSparklineGroup->m_eType);
+    }
+    // Sparkline at Sheet2:B2
+    {
+        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 1, 
1)); //B2
+        CPPUNIT_ASSERT(pSparkline);
+        auto pSparklineGroup = pSparkline->getSparklineGroup();
+        CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, 
pSparklineGroup->m_eType);
+    }
+    // Sparkline at Sheet2:B2
+    {
+        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(1, 1, 
1)); //B2
+        CPPUNIT_ASSERT(pSparkline);
+        auto pSparklineGroup = pSparkline->getSparklineGroup();
+        CPPUNIT_ASSERT_EQUAL(sc::SparklineType::Line, 
pSparklineGroup->m_eType);
+    }
+    // Sparkline doesn't exists at A4
+    {
+        sc::Sparkline* pSparkline = rDocument.GetSparkline(ScAddress(0, 3, 
0)); //A4
+        CPPUNIT_ASSERT(!pSparkline);
+    }
+
+    closeDocument(mxComponent);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SparklineTest);
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/extras/testdocuments/Sparklines.xlsx 
b/sc/qa/extras/testdocuments/Sparklines.xlsx
new file mode 100644
index 000000000000..3725841603be
Binary files /dev/null and b/sc/qa/extras/testdocuments/Sparklines.xlsx differ
commit 4284576afbca99151de982c0ef2ad16ec14dd832
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Feb 25 11:57:15 2022 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sun Feb 27 20:58:47 2022 +0900

    sc: use enums instead strings for some SparklineGroup props.
    
    Change-Id: I082c0a7693c97a67bc4972398224bce4bdae85eb

diff --git a/sc/inc/SparklineGroup.hxx b/sc/inc/SparklineGroup.hxx
index abc1cc71333c..32e4b757378f 100644
--- a/sc/inc/SparklineGroup.hxx
+++ b/sc/inc/SparklineGroup.hxx
@@ -16,6 +16,27 @@
 
 namespace sc
 {
+enum class SparklineType
+{
+    Line,
+    Column,
+    Stacked
+};
+
+enum class AxisType
+{
+    Individual,
+    Group,
+    Custom
+};
+
+enum class DisplayEmptyCellAs
+{
+    Span,
+    Gap,
+    Zero
+};
+
 class SC_DLLPUBLIC SparklineGroup
 {
 public:
@@ -28,16 +49,16 @@ public:
     Color m_aColorHigh;
     Color m_aColorLow;
 
-    OUString m_sMinAxisType; // individual, group, custom
-    OUString m_sMaxAxisType;
+    AxisType m_eMinAxisType;
+    AxisType m_eMaxAxisType;
 
     double m_fLineWeight; // In pt
 
-    OUString m_sType; // line, column, stacked
+    SparklineType m_eType;
 
     bool m_bDateAxis;
 
-    OUString m_sDisplayEmptyCellsAs; // span, gap, zero
+    DisplayEmptyCellAs m_eDisplayEmptyCellsAs; // span, gap, zero
 
     bool m_bMarkers;
     bool m_bHigh;
diff --git a/sc/source/filter/oox/SparklineFragment.cxx 
b/sc/source/filter/oox/SparklineFragment.cxx
index bfc5a259a883..b4c5089dbfa1 100644
--- a/sc/source/filter/oox/SparklineFragment.cxx
+++ b/sc/source/filter/oox/SparklineFragment.cxx
@@ -90,6 +90,33 @@ void addColorsToSparklineGroup(sc::SparklineGroup& 
rSparklineGroup, sal_Int32 nE
     }
 }
 
+sc::SparklineType parseSparklineType(OUString const& rString)
+{
+    if (rString == "column")
+        return sc::SparklineType::Column;
+    else if (rString == "stacked")
+        return sc::SparklineType::Stacked;
+    return sc::SparklineType::Line;
+}
+
+sc::DisplayEmptyCellAs parseDisplayEmptyCellAs(OUString const& rString)
+{
+    if (rString == "span")
+        return sc::DisplayEmptyCellAs::Span;
+    else if (rString == "gap")
+        return sc::DisplayEmptyCellAs::Gap;
+    return sc::DisplayEmptyCellAs::Zero;
+}
+
+sc::AxisType parseAxisType(OUString const& rString)
+{
+    if (rString == "group")
+        return sc::AxisType::Group;
+    else if (rString == "custom")
+        return sc::AxisType::Custom;
+    return sc::AxisType::Individual;
+}
+
 void addAttributesToSparklineGroup(sc::SparklineGroup& rSparklineGroup,
                                    const AttributeList& rAttribs)
 {
@@ -98,11 +125,13 @@ void addAttributesToSparklineGroup(sc::SparklineGroup& 
rSparklineGroup,
 
     rSparklineGroup.m_fLineWeight = rAttribs.getDouble(XML_lineWeight, 0.75);
 
-    rSparklineGroup.m_sType = rAttribs.getString(XML_type, "line");
+    OUString sType = rAttribs.getString(XML_type, "line");
+    rSparklineGroup.m_eType = parseSparklineType(sType);
 
     rSparklineGroup.m_bDateAxis = rAttribs.getBool(XML_dateAxis, false);
 
-    rSparklineGroup.m_sDisplayEmptyCellsAs = 
rAttribs.getString(XML_displayEmptyCellsAs, "zero");
+    OUString sDisplayEmptyCellsAs = 
rAttribs.getString(XML_displayEmptyCellsAs, "zero");
+    rSparklineGroup.m_eDisplayEmptyCellsAs = 
parseDisplayEmptyCellAs(sDisplayEmptyCellsAs);
 
     rSparklineGroup.m_bMarkers = rAttribs.getBool(XML_markers, false);
     rSparklineGroup.m_bHigh = rAttribs.getBool(XML_high, false);
@@ -113,16 +142,19 @@ void addAttributesToSparklineGroup(sc::SparklineGroup& 
rSparklineGroup,
     rSparklineGroup.m_bDisplayXAxis = rAttribs.getBool(XML_displayXAxis, 
false);
     rSparklineGroup.m_bDisplayHidden = rAttribs.getBool(XML_displayHidden, 
false);
 
-    rSparklineGroup.m_sMinAxisType = rAttribs.getString(XML_minAxisType, 
"individual");
-    rSparklineGroup.m_sMaxAxisType = rAttribs.getString(XML_maxAxisType, 
"individual");
+    OUString sMinAxisType = rAttribs.getString(XML_minAxisType, "individual");
+    rSparklineGroup.m_eMinAxisType = parseAxisType(sMinAxisType);
+
+    OUString sMaxAxisType = rAttribs.getString(XML_maxAxisType, "individual");
+    rSparklineGroup.m_eMaxAxisType = parseAxisType(sMaxAxisType);
 
     rSparklineGroup.m_bRightToLeft = rAttribs.getBool(XML_rightToLeft, false);
 
     rSparklineGroup.m_sUID = rAttribs.getString(XML_uid, OUString());
 
-    if (rSparklineGroup.m_sMaxAxisType == "custom")
+    if (rSparklineGroup.m_eMaxAxisType == sc::AxisType::Custom)
         rSparklineGroup.m_aManualMax = oManualMax.get();
-    if (rSparklineGroup.m_sMinAxisType == "custom")
+    if (rSparklineGroup.m_eMinAxisType == sc::AxisType::Custom)
         rSparklineGroup.m_aManualMin = oManualMin.get();
 }
 
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 51535123e208..358688c15d90 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -2432,12 +2432,13 @@ void drawSparkline(sc::Sparkline* pSparkline, 
vcl::RenderContext& rRenderContext
         }
     }
 
-    if (pSparklineGroup->m_sType == "column")
+    if (pSparklineGroup->m_eType == sc::SparklineType::Column)
     {
         drawColumn(rRenderContext, rRectangle, aValues, nMin, nMax);
     }
-    else if (pSparklineGroup->m_sType == "stacked")
+    else if (pSparklineGroup->m_eType == sc::SparklineType::Stacked)
     {
+        // transform the data to 1, -1
         for (auto & rValue : aValues)
         {
             if (rValue != 0.0)
@@ -2445,7 +2446,7 @@ void drawSparkline(sc::Sparkline* pSparkline, 
vcl::RenderContext& rRenderContext
         }
         drawColumn(rRenderContext, rRectangle, aValues, -1, 1);
     }
-    else if (pSparklineGroup->m_sType == "line")
+    else if (pSparklineGroup->m_eType == sc::SparklineType::Line)
     {
         drawLine(rRenderContext, rRectangle, aValues, nMin, nMax);
     }

Reply via email to