78 Commits
Author SHA1 Message Date
FredApps 94a8fb084a Merge pull request #1152 from vangel76/perf/chart-measure-allocs
Charts: label fitting and legend measuring avoid hundreds of text layouts per render (#1149)
2026-11-08 12:08:59 +01:00
FredApps fca22f6e93 Merge pull request #1155 from vangel76/fix/chart-work-budgets
Charts: work and memory are bounded by series x points; ranges are clipped before evaluation (#1147)
2026-11-08 12:08:35 +01:00
vangel76andClaude Sonnet 5.5 9354fdb0c4 Chart: fit labels with a line break by a linear scan
The width of a prefix plus an ellipsis is not monotone when the text has a
line break, so the binary search could drop a label that fits. Also pass the
series index to plot_kind in the data table (upstream/main does not compile
without it).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 17:37:20 +01:00
vangel76 5f84fadaf5 Merge remote-tracking branch 'upstream/main' into c1152 2026-11-07 17:32:43 +01:00
vangel76 9ba79c3e38 fmt 2026-11-07 17:31:41 +01:00
vangel76andClaude Sonnet 5.5 6a7cf9cf66 Chart: bound the category axis by the point cap, not the raw cell count
Read only the cells the category levels use and cut the category dimension
at the per-series cap, so a multi-level axis keeps all its levels.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 17:31:27 +01:00
vangel76andClaude Sonnet 5.5 c35878948a Merge upstream/main into fix/chart-work-budgets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 17:31:27 +01:00
FredApps 6b19e445f4 fix(chart): pass series index to data-table keys (#1150) 2026-11-07 17:27:25 +01:00
FredApps 505cae34c8 Merge pull request #1150 from vangel76/fix/chart-combo-logic-cleanup
Charts: one combo plot-kind function, no dead scale helpers (#1146)
2026-11-07 16:52:46 +01:00
vangel76andClaude Sonnet 5.5 bc1625248e Chart: cap category levels in the clean-data check, recompute overflowing moving-average windows, keep disjoint stacked hairline spans apart
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 16:25:23 +01:00
vangel76andClaude Sonnet 5.5 558312cb53 Merge upstream/main into c1155
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 05:20:58 +01:00
Francisco Herreraandalosslessdev 1fb191571b Charts: draw every doughnut series as a ring (#1827)
* Charts: draw every doughnut series as a ring (#1827)

* Charts: submit doughnut hole size and first slice angle when the drag ends (#1827)

---------

Co-authored-by: alosslessdev <alosslessdev@users.noreply.github.com>
2026-11-05 05:13:35 +01:00
vangel76andClaude Sonnet 5.5 23c909e477 chart perf tests: import LegendPos (legend module now imports it itself)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 01:53:24 +01:00
vangel76andClaude Sonnet 5.5 0955378d8e Merge upstream/main into perf/chart-measure-allocs
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-05 01:50:34 +01:00
Dylan M. Taylor f77ed98cdb chart: a series without values takes no category-span entries (#3300) 2026-11-03 22:56:56 -05:00
Dylan M. Taylor cdd3a59dbc Treemap rows keep running aggregates; General-fit width is clamped (#3290) 2026-11-03 22:55:35 -05:00
Hector VillarrealandClaude Opus 5.5 2caf435a38 #2012: split a parsed sheet-qualified name at the last !, sheet as is
Addresses review comments 4455115540 and 4455115557. The parser stores
`'Sheet'!Name` as `Sheet!Name` with the sheet already unquoted:

- Evaluator::name split it at the first `!`, so a series named
  `'a!b'!Title` showed #NAME?.
- chart_name unquoted it again, trimming spaces, so a chart reference
  to `' Sales '!Data` was saved as `Sales!Data`.

Both now split at the last `!` and look the sheet up as is.

Tests: chart tests::a_series_named_by_a_name_on_a_sheet_with_a_bang_resolves,
xlsx tests::chart_book_names::chart_names_keep_spaces_around_a_quoted_sheet_name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 07:21:22 -06:00
Hector VillarrealandClaude Opus 5.5 e89ba799e9 #2012: chart names and macro examples unquote sheet names like formulas do
Three places still split a `Sheet!Name` reference and stripped the
sheet's quotes by hand: the chart resolver (is a series name a defined
name?), the XLSX chart writer (the name's cache) and the macro editor's
example references. The first two left a doubled quote in the name, so
a series named `'Bob''s'!Title` (a name on the sheet "Bob's") wasn't
found and showed that text instead of the name's value; they also split
at the first `!`, so a quoted sheet holding one broke. All three now use
core's split_sheet, the one reading formulas use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 01:49:01 -06:00
vangel76andClaude Sonnet 5.5 4fe0816ca0 Merge upstream/main into fix/chart-work-budgets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-02 19:49:07 +01:00
Neil Cawse eea1fc276f Charts: decimate area top and baseline at paired horizontal indices 2026-11-02 17:52:23 +00:00
campbellcodyandCodex b6c4500fa7 M7: add data tables beneath charts
Add command and UI controls for chart data tables, shared chart and PDF rendering, and native XLSX persistence. Cover live values, blanks, formatting, alignment, undo/redo, bounds and table flags with regression tests.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-01 15:30:46 -05:00
vangel76andClaude Sonnet 5.5 494a7dbb5c Keep clustered hairline bars of each series in their own strip of the pixel column
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 00:54:56 +01:00
vangel76 95c3bb9b89 Fix clippy complexity after merging upstream/main 2026-10-29 23:05:54 +01:00
vangel76 72e959f117 Merge upstream/main into fix/chart-work-budgets 2026-10-29 23:04:21 +01:00
vangel76 bc7e37fa7d Merge upstream/main into fix/chart-combo-logic-cleanup 2026-10-29 23:03:18 +01:00
Dylan M. Taylor 7fbf3f60c8 Refactor chart for strict Clippy checks 2026-10-28 10:52:53 +00:00
vangel76andClaude Sonnet 5.5 2fe8a33c5d Merge upstream/main into fix/chart-combo-logic-cleanup
render.rs was split into render/ modules on main; the plot-kind and fixed-scale cleanups are re-applied in the new modules.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 19:52:57 +01:00
vangel76andClaude Sonnet 5.5 2f36fe1b34 Merge upstream/main into perf/chart-measure-allocs
render.rs was split into render/ modules on main; the label-fitting, legend and treemap changes are re-applied in the new modules.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 19:51:31 +01:00
vangel76andClaude Sonnet 5.5 5144ebe1de Merge upstream/main into fix/chart-work-budgets
render.rs was split into render/ modules on main; the budget and hairline-bar changes are re-applied in render.rs and render/cartesian.rs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 19:47:54 +01:00
aiongg 3813413b65 refactor(chart): move render.rs items to render/ 2026-10-26 19:04:52 +00:00
vangel76andClaude Sonnet 5.5 ee13457b2f Merge upstream/main into fix/chart-combo-logic-cleanup
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 23:55:05 +01:00
vangel76andClaude Sonnet 5.5 8ae680547a Merge upstream/main into fix/chart-work-budgets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 23:54:05 +01:00
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
vangel76andClaude Sonnet 5.5 8f34c42e88 Merge upstream/main into fix/chart-combo-logic-cleanup
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 10:22:03 +01:00
vangel76andClaude Sonnet 5.5 6c32845740 Merge upstream/main into fix/chart-work-budgets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 10:19:09 +01: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
vangel76andClaude Opus 5.5 a34e109451 Merge upstream/main into perf/chart-measure-allocs
Also removes conflict markers committed to ROADMAP.md by the previous merge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 19:53:52 +02: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
vangel76 c0d0d909fc Merge remote-tracking branch 'upstream/main' into fix/chart-work-budgets
# Conflicts:
#	ROADMAP.md
#	crates/chart/src/resolve.rs
2026-10-22 19:43:16 +02:00
vangel76 562004f198 Merge remote-tracking branch 'upstream/main' into perf/chart-measure-allocs
# Conflicts:
#	ROADMAP.md
2026-10-22 19:35:18 +02:00
vangel76 7f8ac83dc3 Merge remote-tracking branch 'upstream/main' into fix/chart-combo-logic-cleanup
# Conflicts:
#	ROADMAP.md
#	crates/chart/src/tests.rs
2026-10-22 19:34:40 +02: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