diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2022-02-28 15:35:48 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2022-03-22 08:44:44 +0100 |
commit | 6c16dc217ef5cbe25166df7a3728ade12a148880 (patch) | |
tree | 964d896bfd1b8d3118f82c9035086a228743fc24 /sc | |
parent | adf924ce6742a419e6a082ebd60d58d296e2971e (diff) |
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 <quikee@gmail.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/ui/view/output.cxx | 116 |
1 files changed, 103 insertions, 13 deletions
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index 6888775df3f7..980f9ff47687 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -2322,35 +2322,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; @@ -2367,11 +2455,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; @@ -2384,6 +2476,7 @@ void drawColumn(vcl::RenderContext& rRenderContext, tools::Rectangle const & rRe rRenderContext.DrawPolygon(aPolygon); } xStep++; + nValueIndex++; } } @@ -2399,9 +2492,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; @@ -2442,7 +2532,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) { @@ -2452,11 +2542,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 |