Skip to content

Improve XLSX clustered column chart visual parity - #156

Merged
shps951023 merged 1 commit into
mainfrom
fix/xlsx-chart-legend-gap-width
Sep 8, 2026
Merged

shps951023 merged 1 commit into
mainfrom
fix/xlsx-chart-legend-gap-width

Conversation

@shps951023

@shps951023 shps951023 commented Sep 8, 2026 •

Copy link
Copy Markdown
Member

Summary

  • align narrow positive column-chart axes with LibreOffice auto-scaling
  • parse and render explicit right-side legends and built-in style 10 framing
  • honor OOXML c:gapWidth for vertical and horizontal bar charts
  • preserve existing multi-page chart slice geometry
  • add a real XLSX regression fixture, focused assertions, reference PDF, comparison images, heatmap, and score report

Fixes #155

Validation

  • dotnet test tests/MiniPdf.Tests — 189 passed, 0 failed
  • scripts/Run-Benchmark_issues.ps1 -Filter "XlsxIssue152_ClusteredNonZeroBarChart" -Engine libre -SkipInstall -Heatmaps
    • pages: MiniPdf 1 / LibreOffice 1
    • text similarity: 0.9771
    • visual similarity: 0.9652
    • overall score: 0.9769

Summary by CodeRabbit

  • New Features

    • Improved Excel chart rendering with support for legend placement, chart styles, and configurable bar spacing.
    • Enhanced compact chart layouts with borders, improved title formatting, expanded margins, and right-side legends.
    • Improved scaling for clustered bar charts with positive, non-zero data.
  • Tests

    • Added coverage for clustered bar charts, including gap width, labels, legend placement, and bold titles.
    • Updated comparison reports and visual benchmarks for the new chart rendering behavior.

Copilot AI lite review requested due to automatic review settings September 8, 2026 02:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new right-side legend rendering can lead to duplicated legends (existing default legend plus the new right legend), which is a correctness/layout issue that should be resolved before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR improves XLSX clustered column/bar chart rendering parity (targeting LibreOffice behavior) by parsing additional OOXML chart metadata and updating rendering/layout logic, plus adding a focused regression test and updating the checked-in benchmark reports/manifest to include the new fixture.

Changes:

  • Parse chart legend position, built-in chart style, and <c:gapWidth> from OOXML and plumb them through ExcelChartInfo.
  • Update chart rendering to (a) apply a style-10 frame/title layout when the chart fits on-page, (b) render a right-side legend when explicitly requested, (c) honor gapWidth for bar sizing, and (d) adjust narrow-positive-range autoscaling.
  • Add/strengthen regression assertions for axis bounds, bar spacing, series name legend text, and style-10 title bolding; update benchmark report artifacts to include the new case.
File summaries
File Description
tests/MiniPdf.Tests/ExcelToPdfConverterTests.cs Strengthens the clustered non-zero bar/column chart regression test with gap/axis/title/legend assertions.
src/MiniPdf/ExcelReader.cs Parses chart style, legend position, and gap width from chart XML into ExcelChartInfo.
src/MiniPdf/ExcelToPdfConverter.cs Updates chart rendering/layout (style 10 framing, right-side legend, axis scaling tweak, gapWidth sizing).
tests/Issue_Files/reports_xlsx/comparison_report.md Updates the checked-in benchmark report to include the new XLSX fixture and updated summary sections.
tests/Issue_Files/reports_xlsx/comparison_report.json Adds the new case’s JSON report entry (scores, pages, diff metadata).
tests/Issue_Files/reports_xlsx/comparison_manifest.json Adds the new case to the report manifest and normalizes formatting.
Review details

Suppressed comments (2)

src/MiniPdf/ExcelToPdfConverter.cs:2894

  • The right-legend layout uses the series loop index to compute entryY; if some series names are empty, this leaves vertical gaps (and can push later entries outside the allocated legend area sooner). Track a separate entry index that only increments when an entry is actually rendered.
            {
                var seriesName = chart.Series[index].Name;
                if (string.IsNullOrEmpty(seriesName)) continue;
                var entryY = legendY - index * (labelFontSize + 6f);
                page.AddRectangle(legendX, entryY, 7f, 7f, ChartColors[index % ChartColors.Length]);

src/MiniPdf/ExcelToPdfConverter.cs:2806

  • legendWidth is capped at 32pt / 10% chart width, but the legend text is drawn without clipping and can extend past the chart (and even the page when the chart is near the right edge). It would be safer to size legendWidth based on the measured max series-name width (plus swatch/padding) and clamp it to the available width, so plotRight and the legend stay within bounds.
            && chart.Series.Any(series => !string.IsNullOrEmpty(series.Name))
            && chartFitsPage;
        var legendWidth = showRightLegend ? Math.Min(32f, width * 0.1f) : 0f;
        var plotLeft = x + padding + (useStyle10Layout ? 47f : 40f);
        var plotRight = x + width - padding - 10f - legendWidth;
  • Files reviewed: 6/11 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +2801 to +2803
var showRightLegend = chart.LegendPosition is "r" or "tr"
&& chart.Series.Any(series => !string.IsNullOrEmpty(series.Name))
&& chartFitsPage;
@shps951023
shps951023 merged commit aac1a46 into main Sep 8, 2026
3 of 4 checks passed
@coderabbitai

coderabbitai Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 0df53222-88da-44a2-bf22-51831c94c913

📥 Commits

Reviewing files that changed from the base of the PR and between 22719bf and 0f28f70.

⛔ Files ignored due to path filters (5)
  • tests/Issue_Files/reference_xlsx/XlsxIssue152_ClusteredNonZeroBarChart.pdf is excluded by !**/*.pdf
  • tests/Issue_Files/reports_xlsx/images/XlsxIssue152_ClusteredNonZeroBarChart_p1_heatmap.png is excluded by !**/*.png
  • tests/Issue_Files/reports_xlsx/images/XlsxIssue152_ClusteredNonZeroBarChart_p1_minipdf.png is excluded by !**/*.png
  • tests/Issue_Files/reports_xlsx/images/XlsxIssue152_ClusteredNonZeroBarChart_p1_reference.png is excluded by !**/*.png
  • tests/Issue_Files/xlsx/XlsxIssue152_ClusteredNonZeroBarChart.xlsx is excluded by !**/*.xlsx
📒 Files selected for processing (6)
  • src/MiniPdf/ExcelReader.cs
  • src/MiniPdf/ExcelToPdfConverter.cs
  • tests/Issue_Files/reports_xlsx/comparison_manifest.json
  • tests/Issue_Files/reports_xlsx/comparison_report.json
  • tests/Issue_Files/reports_xlsx/comparison_report.md
  • tests/MiniPdf.Tests/ExcelToPdfConverterTests.cs

📝 Walkthrough

Walkthrough

The change parses chart style, legend position, and gap width from XLSX chart XML. It applies these values to chart layout, legends, bar sizing, and axis scaling. Tests and LibreOffice comparison reports cover a clustered non-zero column chart.

Changes

XLSX chart parity

Layer / File(s) Summary
Chart metadata extraction
src/MiniPdf/ExcelReader.cs
ExcelChartInfo now carries chart style, legend position, and optional gap width parsed from chart XML.
Chart layout and bar sizing
src/MiniPdf/ExcelToPdfConverter.cs
Style 10 charts use a bordered layout with bold titles. Right-side legends render when applicable. Bar and horizontal bar spacing uses GapWidthPercent. Clustered positive charts use updated lower-axis bounds.
Regression fixture and comparison validation
tests/MiniPdf.Tests/ExcelToPdfConverterTests.cs, tests/Issue_Files/reports_xlsx/*
The regression fixture and assertions cover chart metadata, spacing, labels, and title weight. Comparison data and reports include XlsxIssue152_ClusteredNonZeroBarChart and LibreOffice references.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant XLSXChartXml
  participant ExcelReader
  participant ExcelToPdfConverter
  participant ComparisonTests
  XLSXChartXml->>ExcelReader: provide style, legend position, and gap width
  ExcelReader->>ExcelToPdfConverter: pass ExcelChartInfo metadata
  ExcelToPdfConverter->>ComparisonTests: render chart PDF
  ComparisonTests->>ComparisonTests: validate layout, labels, spacing, and title
Loading

Suggested reviewers: enzosam

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/xlsx-chart-legend-gap-width

Comment @coderabbitai help to get the list of available commands.

@shps951023
shps951023 deleted the fix/xlsx-chart-legend-gap-width branch September 16, 2026 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve XLSX clustered column chart visual parity

2 participants