sc/inc/Sparkline.hxx | 2 sc/source/filter/oox/SparklineFragment.cxx | 2 sc/source/ui/view/output.cxx | 116 +++++++++++++++++++++++++---- 3 files changed, 105 insertions(+), 15 deletions(-)
New commits: commit 7188e67c74c9e26e45ed994171620311a0e92be4 Author: Andrea Gelmini <[email protected]> AuthorDate: Wed Mar 9 05:38:05 2022 +0100 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Mon Apr 11 01:58:28 2022 +0200 Fix typos Change-Id: Ibaefacb89a680f5d7a34e64fdf856fbd0575ee4e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131226 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <[email protected]> (cherry picked from commit 84e56886d7470b9a51740b831047132922daacce) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132773 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Tomaž Vajngerl <[email protected]> diff --git a/sc/inc/Sparkline.hxx b/sc/inc/Sparkline.hxx index c8bb4d1baa22..0c5a9deeb774 100644 --- a/sc/inc/Sparkline.hxx +++ b/sc/inc/Sparkline.hxx @@ -20,7 +20,7 @@ namespace sc /** Sparkline data, used for rendering the content of a cell * * Contains the input range of the data that is being drawn and a reference - * to the SparklineGroup, which inclues common properties of multiple + * to the SparklineGroup, which includes common properties of multiple * sparklines. */ class SC_DLLPUBLIC Sparkline diff --git a/sc/source/filter/oox/SparklineFragment.cxx b/sc/source/filter/oox/SparklineFragment.cxx index f590aaee235b..ce398169972e 100644 --- a/sc/source/filter/oox/SparklineFragment.cxx +++ b/sc/source/filter/oox/SparklineFragment.cxx @@ -224,7 +224,7 @@ void SparklineGroupsContext::onCharacters(const OUString& rChars) rLastSparkline.m_aTargetRange = aRange; // Need to set the current sheet index to the range as - // it is assumed that the address string referes to + // it is assumed that the address string refers to // the current sheet and is not defined in the string. for (auto& rRange : rLastSparkline.m_aTargetRange) { commit b5e12b22c9810d1527f5d55cf2221fc00d598a36 Author: Tomaž Vajngerl <[email protected]> AuthorDate: Mon Feb 28 15:35:48 2022 +0900 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Mon Apr 11 01:58:15 2022 +0200 sc: support sparkline bar colors, add markers to sparkline lines Change-Id: I705a7f57cc4d6544ecb35a5f93c18a27056b9944 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131918 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <[email protected]> (cherry picked from commit 6c16dc217ef5cbe25166df7a3728ade12a148880) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132772 Tested-by: Tomaž Vajngerl <[email protected]> diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index 86d37d8d6cc2..fc7711f5befe 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -2306,35 +2306,123 @@ 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; +} + /** Draw a line chart into the rectangle bounds */ 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); + } } /** Draw a column chart into the rectangle bounds */ 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; @@ -2351,11 +2439,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; @@ -2368,6 +2460,7 @@ void drawColumn(vcl::RenderContext& rRenderContext, tools::Rectangle const & rRe rRenderContext.DrawPolygon(aPolygon); } xStep++; + nValueIndex++; } } @@ -2383,9 +2476,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; @@ -2426,7 +2516,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) { @@ -2436,11 +2526,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
