Skip to content

feat(xlsx): chart fills, lines and text as the file gives them - #14

Closed
mkroemer wants to merge 6 commits into
p10node:mainfrom
mkroemer:xlsx-chart-looks
Closed

mkroemer wants to merge 6 commits into
p10node:mainfrom
mkroemer:xlsx-chart-looks

Conversation

@mkroemer

Copy link
Copy Markdown

Builds on the charts PR (#12). Until that is merged this PR shows its commits too; this part is the last commit.

Charts drawn by #12 take their colors from the series and fall back to the theme's accents. Many real workbooks style their charts further, and those charts looked plainer than in Excel. This reads the rest of the look from the chart part and draws it:

  • Gradient fills (linear and radial) and pattern fills (the DrawingML presets, drawn as an 8 × 8 SVG pattern) on series, single points, the chart area and the plot area. Each chart is its own <img>, so the gradient and pattern ids only need to be unique within one picture.
  • The text size, weight and color of axis labels, the legend and data labels (c:txPr), so a dark chart's light text stays readable.
  • Gridlines and axis lines with their own color, width and dash, or none.
  • The plot area's own fill and border.
  • The built-in chart style (c:style, and Excel 2010's c14:style) for what the file leaves to it: the gray, accent and one-accent palettes, the tinted plot areas of the fifth row and the dark backgrounds of the sixth. Bevels and shadows are not drawn.
  • The default grays (text, gridlines, axis lines) are now shades of the theme's text color, as Excel derives them, rather than fixed hex values.

test/xlsx-chart.test.ts adds a gradient and a pattern fill, axis and legend text colors, dashed gridlines and a plot area fill, the theme's default grays, a dark built-in style and a one-accent style. bun run typecheck, bun test and the e2e suite pass in CI.

🤖 Generated with Claude Code

markus-kroemer and others added 6 commits November 14, 2026 07:58
A sheet's drawing part (xl/drawings/drawingN.xml) is read for its
pictures and charts with their anchors: two cells, one cell and a size,
or a position and a size. The new `xlsx.drawings(sheet)` call returns
them; the grid lays them over the cells, placed by the row and column
axes, so a picture moves and grows with resized or hidden rows and
columns, and the sheet extends far enough to reach every drawing.

A picture the browser can draw (PNG, JPEG, GIF, SVG, ...) is shown as
itself, through the client's media URLs. A chart, and a picture in a
format the browser cannot draw (EMF, WMF), is shown as a box of its
size naming what is there: the chart's kind (column, bar, line, pie,
...) and title. Shapes and text boxes are left out. Clicks go through
to the cells below.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A sheet's charts were placeholders. Now src/core/xlsx/chart.ts reads a
chart part into a model in the worker, and src/core/xlsx/chart-svg.ts
draws it as a self-contained SVG (DOM-free), shown over the cells like a
picture.

- Kinds: bar and column (clustered, stacked, 100%, upright or
  horizontal), line (markers, smoothing, gaps for empty cells), area,
  pie and doughnut (exploded slices, first-slice angle), scatter, and
  combinations on primary and secondary axes; 3D charts as their flat
  form. Radar, bubble, stock, surface and chartex keep the placeholder.
- Values: series references are read from the workbook's cells, loading
  a sheet not shown yet, so charts follow edits (the view reads them
  again after an edit result). A defined name, another workbook or an
  unreadable reference falls back to the chart's numCache / strCache.
  Hidden rows and columns are left out when plotVisOnly is set.
- Look: Excel-like automatic axis bounds (zero kept, steps of 1/2/5),
  fixed min/max/major unit, reversed and log axes, gridlines, tick and
  data labels in their number formats, tilted category labels where they
  do not fit flat, title (Excel's automatic one included), legend
  (positions, overlay, deleted entries), theme accents for series
  without colors of their own, manual plot layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pie negatives, cell titles

- scatter: a point whose X value is missing is not drawn (it was placed at
  its ordinal position); value labels follow their own points when a Y
  value is missing
- bars, areas, lines and points are clipped to the plot area, so a fixed
  axis range does not let them run over the title and legend
- pie and doughnut: a negative value is a slice of its magnitude, as in
  Excel; its value label keeps the sign
- a title whose text is a cell (`c:tx/c:strRef`) shows that cell's text,
  else its cached text, before the automatic title

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… row stays in it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The automatic bounds add a step above a maximum that falls on a
gridline, so a 100% stacked axis ran to 120%. An axis carrying only
100% stacks now ends at 100% (and -100% with negatives), as Excel's does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- gradient fills (linear and radial) and pattern fills (DrawingML presets)
  for series, points, the chart area and the plot area
- the text size, weight and color of axis labels, legend and data labels
- gridline and axis lines: color, width, dash, or none
- the plot area's fill and border
- the built-in chart style (c:style, c14:style): gray, accent and
  one-accent palettes, tinted plot areas, dark backgrounds
- default grays (text, gridlines, axis lines) as shades of the theme's
  text color rather than fixed values

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mkroemer

Copy link
Copy Markdown
Author

Folded into #12, which now carries these commits, so the charts can be reviewed in one place.

@mkroemer mkroemer closed this Nov 15, 2026
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.

2 participants