Commit Graph
37 Commits
Author SHA1 Message Date
3b65b9af58 Sonar maintainability: explicit imports, method paths, smaller functions (#2412)
* Sonar: explicit imports, fn paths for closures, extract helpers for cognitive complexity

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

* Fix imports

* Fix serde imports

* Fix engine imports

* Fix clippy gate and a type error from the explicit-import change

Remove the unused imports the review flagged (cf.rs, pivot.rs, tables.rs, cmd/sheet.rs) so clippy -D warnings passes, and point the backstage parent-folder lookup at Path::to_str, which the fn-path rewrite had broken.

Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Apply rustfmt to the explicit-import cleanup so the fmt gate passes

* Share the per-directory font path expansion in theme.rs

The candidate font lists repeated the same loop over the Linux font
directories in every role. A single helper expands them in the same order,
so the lookup order is unchanged and the duplicated blocks go away.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Read the Windows fonts folder in one place in theme.rs

Every script-font list repeated the same WINDIR lookup. A single helper
returns the same path, so the duplicated lines go away without changing
which font files are tried.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Build the light and dark UI palettes from one table in theme.rs

Tokens::light() and Tokens::dark() listed the same 40 colour fields in the
same order, so every change had to be made twice. A single palette
constructor takes the mode and picks each colour's value, so each field is
written once and both modes keep their exact colours.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Share the Noto CJK font list between the CJK script lists in theme.rs

The Japanese, Simplified and Korean lists each repeated the same loop over
the Linux CJK directories with a different locale file name. One helper
builds that loop, and each list keeps its own face index, so the lookup
order is unchanged.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

* Share Linux Noto directory list across Thai and Hebrew font lookups

Removes the duplicated directory arrays flagged by SonarCloud new-code duplication.

* Reuse in_dirs for Thai and Hebrew Noto font candidates

Removes the remaining duplicated per-directory loops flagged by SonarCloud.

* Share one font-list builder for the Thai and Hebrew faces

The two per-script functions repeated the same Windows, macOS, Linux and
variable-font setup. A single script_fonts helper now builds both lists,
keeping the candidate order unchanged, which clears the Sonar duplication gate.

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Codebuff <noreply@codebuff.com>
2026-10-25 12:32:02 -04:00
dotCooCoo 0eb2f1f6f0 Charts: 100% Stacked Area draws each value as a share of its category's total
Insert > Line or Area and the All Charts list offer 100% Stacked Area,
and insert.chart and chart.set take it as type area with subtype
stacked100. Each series' area stacks on the ones before it as its
share of the category's total. When every series on the value axis is
100% stacked and no value is negative, the axis runs from 0% to 100%.
A blank cell counts as zero, and a category whose total is zero stays
on the baseline.

An XLSX area chart with percentStacked grouping now opens as 100%
stacked and is saved back as percentStacked. It used to open as a
stacked area and was saved as stacked.
2026-10-24 16:42:59 -07:00
Dylan M. Taylor 10bec74810 M6: misc hardening — unbounded picture cache, stats walk, signing tmpdir, web clipboard, dash budget, fs cycle, rezip loop (#2422)
- floating_pictures: draw without retaining when eviction can't free
  enough room, so a large workbook can't pin the cache past its budget
- xtask stats: skip unreadable subtrees instead of aborting the walk
- import-cert.sh: per-run private temp dir instead of predictable
  paths in a shared root
- gridcraft-web: gate clipboard ops behind user activation
- chart raster: cap dash rendering to the stroked budget
- cli check: mark directories visited by identity on unix so hard-link
  loops can't recurse; reuse one decompression of a reused part
2026-10-24 06:33:19 -04:00
aiongg c7fd66d807 Integration: track t12
# Conflicts:
#	ROADMAP.md
#	crates/calc/src/tests.rs
#	crates/chart/src/tests.rs
#	crates/engine/src/tests.rs
#	crates/xlsx/src/tests/mod.rs
#	docs/chart-parity.md
2026-10-22 03:05:03 +00:00
aiongg 54d0f7cfc0 Integration: track t02
# Conflicts:
#	ROADMAP.md
#	crates/core/src/lib.rs
#	crates/ui-egui/src/editor.rs
#	crates/ui-egui/src/grid.rs
#	crates/ui-egui/src/tabs.rs
#	docs/chart-parity.md
#	docs/localization-parity.md
#	docs/ui-parity.md
2026-10-22 02:59:55 +00:00
aiongg c37298b468 Integration: #1151 test literal gains the category_levels field from #1088 2026-10-22 02:40:38 +00:00
aiongg 1316d39865 Merge PR #1151: Charts: a huge trendline forecast no longer collapses the chart (#1148)
ROADMAP.md: all rows kept.
crates/chart/src/tests.rs: both tests kept.
2026-10-22 02:37:37 +00:00
aiongg 6370fd2254 Merge PR #1693: Charts: series that refer to defined names ([0]!Name) plot their data, and are saved qualified
crates/xlsx/src/tests/mod.rs: kept both mod lines (cellmetadata, chart_book_names)
docs/file-format-parity.md: kept HEAD header line, both change rows
2026-10-22 02:36:34 +00:00
Eduardo GarciaandClaude Sonnet 5.5 0b4cc5618f fix #1458: one Excel sheet-name quoting rule for formulas, pivot sources and ADDRESS
Sheet names starting with '.' or reading as R1C1 (R, C, RC, R1C1...) were saved
unquoted, so Excel could not open the file; PivotTable sources and ADDRESS left
cell-like names (A1) bare. The quoting rule, unquoting and sheet splitting now
live once in gridcraft_core::addr and replace the copies in the formula printer,
pivot, ADDRESS, chart, xlsx, Solver, Go To and the Name Box (which now reads ''
as ').

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 17:36:40 -03:00
webdevtodayjason ea3ef8faf7 Charts: honor box and whisker quartile methods
Keep exclusive and inclusive quartiles per series when drawing and saving XLSX, and expose the setting through chart.set.

Fixes #1453
2026-10-16 12:37:27 -05:00
Nick GillandClaude Opus 5.5 8e7438b434 Charts: write names in chart references qualified, as Excel needs (#1686)
Checked black-box in Excel for Windows (Microsoft 365) with synthetic
workbooks: a bare name in <c:f> draws the whole chart blank, without a
repair prompt, for workbook- and sheet-scoped names alike, while
`[0]!Name` and `Sheet1!Name` plot.

- Write: a sheet-scoped name is written `Sheet!Name` (quoted when
  needed) instead of bare; an already qualified name keeps its sheet;
  an undefined name gets `[0]!`. A reference to an unknown sheet is
  kept as written. A qualified series name is written as a strRef.
- Resolve: a series name `Sheet1!Name` is looked up on that sheet, as
  the evaluator does, instead of being shown as literal text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 13:32:54 -04:00
Nick GillandClaude Opus 5.5 e8f049943f Charts: series that refer to workbook names ([0]!Name) plot their data (#1686)
Excel writes a workbook-scoped defined name in a chart reference as
`[0]!Name`. The reader kept that text, the lexer took `[0]` for a
structured reference, and the series evaluated to #NAME?: a chart over
dynamic (OFFSET) names opened blank with one #NAME? category.

- Read: `[0]!Name` becomes `Name` in c:f (cat, val, xVal, yVal,
  bubbleSize, tx), chartex cx:f and _xlchart names. External books
  ([1]Sheet1!...), quoted sheet names and strings are untouched.
- Write: a bare workbook-scoped name is written back as `[0]!Name`; a
  sheet-scoped name stays bare. A series name that is a defined name is
  written as a strRef instead of literal text.
- Resolve: a series name that is a defined name is evaluated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 12:54:04 -04:00
vangel76andClaude Sonnet 5.5 568dd58264 Charts: a huge trendline forecast no longer collapses the chart (#1148)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 21:13:05 +02:00
Lexx143andClaude Fable 5.1 209d2447d9 Charts: multi-level category axes, read, drawn and written back
A category range two or more columns wide beside a column of values (year beside month, Excel's
multiLvlStrRef) was read as one flat list: 36 rows in two columns became 72 categories, the
series sat in the left half of the plot and the years and months shared one row of labels.
Saving wrote the range as a plain strRef, so Excel lost the two-level axis too.

- gridcraft_core::category_levels: the shape of a category range beside its values (levels are
  columns when the points run down the rows, rows when they run along the columns; up to three
  outer levels), shared by the chart and xlsx crates.
- ChartData.category_levels: the outer levels, nearest the labels first, one entry per category,
  non-empty where a group starts. resolve fills it; a single column is unchanged.
- render: the outer levels in rows under the labels, a group's name centred under its categories
  with a separator at each boundary; in bar charts in columns beside the labels.
- xlsx: <c:cat> written as multiLvlStrRef with the level caches (innermost first), so the axis
  survives a round trip.

Tests in core (shapes), chart (resolve and layout for columns, bars and a row of values) and
xlsx (written XML, read-back, stability, a single column stays strRef). chart-parity, gaps § 4
and the ROADMAP progress log updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-13 17:30:01 +03:00
Brandon ThomasandClaude Opus 5.5 6405b00cf7 Fix-up: repair test files after merging the conflicting PRs
- restore closing braces the line-level merges of side-by-side tests dropped
- new ChartData literals carry the palette field
- the filter-menu shortcut passes the row with the column
- #688's tab tests account for #851's All Sheets button
- Serbian margins for the ruler-margin labels

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 00:34:01 -04:00
Brandon Thomas d9e13a953f Merge main into #808
# Conflicts:
#	ROADMAP.md
2026-10-13 00:08:30 -04:00
Brandon Thomas 7415d3b37d Merge main into #615
# Conflicts:
#	crates/chart/src/tests.rs
2026-10-13 00:07:34 -04:00
Brandon Thomas f075c63207 Merge main into #614
# Conflicts:
#	crates/chart/src/tests.rs
2026-10-13 00:07:31 -04:00
Brandon Thomas 588e289901 Merge main into #585
# Conflicts:
#	crates/chart/src/tests.rs
2026-10-13 00:07:17 -04:00
Brandon ThomasandClaude Opus 5.5 811a8a139a Fix-up: rustfmt the area-chart label condition after merging the chart PRs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:33:10 -04:00
Brandon Thomas 2f83a04521 Merge pull request #616 from MarekSpodBiedry:issue-542 2026-10-12 23:21:38 -04:00
Brandon Thomas e447fb8c90 Merge pull request #613 from MarekSpodBiedry:issue-545 2026-10-12 23:21:34 -04:00
vangel76andClaude Sonnet 5.5 fd53de7c46 Numfmt: TEXT() and chart labels parse each format code once (#806)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 22:09:09 +02:00
MarekSpodBiedry 91873e03eb Draw data labels on area and stacked area charts (#545) 2026-10-12 08:38:28 +02:00
MarekSpodBiedry 389c539da4 Honour the gridlines flag on box-and-whisker and stock charts (#543) 2026-10-12 08:36:18 +02:00
MarekSpodBiedry 5fb854be9c Chart: color pie, doughnut, treemap and sunburst points from the workbook theme (#579) 2026-10-12 08:36:14 +02:00
MarekSpodBiedry 3301d59f44 Fix histogram counts disagreeing with interval labels on bin boundaries (#546) 2026-10-12 08:35:31 +02:00
MarekSpodBiedry d64b30b3a4 Funnel chart: hide value labels when data labels are off (#544) 2026-10-12 08:29:56 +02:00
MarekSpodBiedry 30fe8c4cae Fix chart rasterizer panic on negative rectangle extents (#542) 2026-10-12 08:29:48 +02:00
neilcawseandClaude Opus 5.5 8ea2342703 Charts: read, write and draw trendlines
Model: Series.trendlines (Vec<Trendline>, serde default) with kind
(linear, exponential, logarithmic, polynomial 2..6, power, moving
average 2..255), name, forward/backward forecast, set intercept,
equation / R² display and line colour, width and dash.

XLSX: read and write <c:trendline> in CT_Trendline child order, placed
after dLbls and before the data references in line, bar, area, scatter,
bubble and stock series; unknown types are skipped.

Chart: least-squares fits (transformed for exp/log/power, skipping
non-positive values; polynomials via normal equations on centred,
scaled x with partial pivoting), moving averages, forecasts that widen
the category or x axis, clipping to the plot, equation and R² labels and
legend entries ("Linear (Sales)"). Degenerate data draws nothing.

Engine: chart.addElement element="trendline" adds (type, series, order,
period, forward, backward, displayEquation, displayRSquared) or removes
trendlines; document.inspect lists each chart's trendlines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:39:31 -04:00
vangel76andClaude Opus 5.5 1a7c16eb9a Charts: PivotCharts (insert.pivotChart) (#311)
A chart linked to a PivotTable: series are built from the report
(innermost row items x column items/value fields, totals excluded) and
rebuilt on every refresh or layout change; c:pivotSource round trip;
chart series accept union references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 12:31:49 +02:00
Brandon Thomas bd1be73f2d Merge pull request #62 from justinjohn0306/fix/smooth-line-charts
Line charts: smooth (spline) curves (issue #52)

# Conflicts:
#	crates/xlsx/src/tests/mod.rs
2026-10-10 13:17:07 -04:00
Brandon ThomasandClaude Opus 5.5 c975b5dc75 Review fix-up: uniform, plot-clamped spline smoothing
smooth_run gives every segment the same number of sub-segments (cap / n, 1..100) so long
series are smoothed end to end within the point cap, and clamps the Catmull-Rom curve to
the plot box. List "smooth" in chart.addElement's params doc, drop the smooth_demo
example, and use the test sheet's own name in series refs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 12:21:35 -04:00
nihilist-narwhal bf1381253f Charts: scatter and bubble charts with text X values number the points
A scatter or bubble chart whose X values are text (a first column of
labels) drew no points, as none of its X values were numbers. Like
Excel, such X values are now ignored and the points numbered 1..n.
2026-10-09 23:31:26 -05:00
justinjohn0306 69709bd458 Line charts: smooth (spline) curves (issue #52)
Add support for Excel's "smoothed line" chart style. The smooth flag flows
model -> resolve -> chart render, persists through XLSX (<c:smooth val="1"/>),
and is toggled via the chart.addElement "smooth" element.

Rendering interpolates each gap-free run with a uniform Catmull-Rom spline
(0.5 tangent scale, 100 sub-segments per data segment), so the curve passes
through every data point and rounds the vertices — matching Excel's observed
behaviour. Long runs are still decimated before smoothing.

- model: Series.smooth (#[serde(default)], so old workbooks load unchanged)
- chart: SeriesData.smooth; smooth_run + catmull in render; wired through
  resolve and the sanitize() copy; draw_runs takes the flag (line + scatter)
- engine: chart.addElement element="smooth"
- xlsx: read/write <c:smooth val> instead of hard-coding val="0"
- tests: smooth_line_adds_interpolated_points_and_keeps_endpoints,
  smooth_line_splits_at_gaps, smooth_line_setting_round_trips
- examples/smooth_demo.rs: generates a straight+smooth side-by-side workbook

cargo xtask ci: all 7 steps pass.
2026-10-10 00:09:12 +05:30
Brandon ThomasandClaude Opus 5.5 488e12de31 Rename SheetCraft to GridCraft everywhere (crates, apps, bundle ids, packaging, docs)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:39:08 -04:00
Brandon ThomasandClaude Opus 5.5 beb353943e M1: Excel-style egui UI, desktop app, chart renderer, MCP server, CLI, release packaging
- ui-egui: title bar with QAT, full ribbon (Home/Insert/Draw/Page Layout/Formulas/Data/
  Review/View/Automate + Table/Chart Design), formula bar with Name Box, virtualised grid
  (frozen panes, overflow, borders, CF data bars/scales/icons, tables, sparklines, filter
  buttons, charts/pictures/shapes), in-cell editor with point mode, reference colouring,
  autocomplete and argument hints, sheet tabs, status bar, dialogs, control channel
- apps/sheetcraft: desktop app (control server, file dialogs, prefs, drag & drop)
- chart: toolkit-free chart layout/rendering for 25 chart kinds + sparklines + rasteriser
- mcp + sheetcraft-cli: MCP server (headless or bridged) and CLI (info/convert/eval/cat/run/mcp)
- xtask (ci/layers/assets/wasm/version/parity), release workflows, packaging, placeholder icon
- automatic row heights

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 00:00:15 -04:00