Skip to content

Bar stack/fill with an x axis: one bar per cell, in x order - #26

Merged
fnaji merged 2 commits into
masterfrom
fix/bar-stack-x-order
Oct 19, 2026
Merged

fnaji merged 2 commits into
masterfrom
fix/bar-stack-x-order

Conversation

@fnaji

@fnaji fnaji commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #25 (1.0.18).

Problem

1.0.18 draws a cell as one stacked bar only when there is no x axis. With an x axis that gives each value of a cell its own position, stack and fill still draw separate bars, the same as dodge. A common case is the colour factor on x, which is what the customer did on tercen.com. There, no x position holds more than one value, so ggplot has nothing to stack.

Fix (utils.R, ChartBar)

  • Stack / fill. When no x position in a layer holds more than one value in its cell, the cell is drawn as one bar. The bar is stacked or filled in x-axis order, first position at the bottom. With no x axis, the order is still the crosstab order (Bar chart without x axis: crosstab order, and stack/fill really stack #25).
  • Values sharing an x. When values share an x position, for example a numeric x with a colour per x, ggplot stacks per x position as before.
  • Dodge. Unchanged.

Verification

Each case ran on local Tercen Studio in dodge, stack and fill. Each was compared with the released 1.0.18 image, once as released and once with this utils.R mounted.

Projection Result
Customer data, x = label (text, also the colour) stack and fill: one bar per cell, in x/legend order. dodge: identical to 1.0.18.
Customer data, no x identical to 1.0.18
Synthetic data, numeric x (Day), 3 colours per x identical to 1.0.18, still stacked per x
Synthetic data, no x identical to 1.0.18

Unit tests (new)

  • Refactor. utils.R moves the bar placement into pure functions: crosstab_x_position, collapse_bars, stack_cells and bar_layer. They can be tested without a Tercen context. The output is unchanged: 12 Studio projections are pixel-identical before and after.
  • unit_tests/run.R. 24 base-R checks, with no testthat added to the image. Each builds the bar layer and reads back what ggplot computes:
    • one bar per cell, and its stack order: crosstab order without x, x order with the colour on x;
    • fill reaching 1;
    • plain ggplot behaviour when values share an x.
  • The checks catch real regressions. They fail on the 1.0.17 read order (4 failures), the 1.0.18 rule that only merges without an x axis (5 failures), and an upside-down stack (6 failures).
  • .github/workflows/unit-tests.yml. Builds the image and runs the tests in it on every pull request and on pushes to master. It is green on this PR.
  • Location. The tests live in unit_tests/, not tests/, which Tercen's installer and the library scan treat as platform golden tests.

🤖 Generated with Claude Code

fnaji and others added 2 commits October 19, 2026 19:17
…an x

1.0.18 collapsed a cell into one stacked bar only without an x axis. With
an x axis that gives every value its own position (e.g. the colour factor
on x), stack and fill still drew separate bars, as ggplot had nothing to
stack at any x. Collapse in that case too, ordering the stack by the x
axis. When values share an x position, stacking per x is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- utils.R: the bar placement moves into pure functions
  (crosstab_x_position, collapse_bars, stack_cells, bar_layer) so it can
  be tested without a Tercen context. The output is unchanged: 12 Studio
  projections (customer and synthetic data, x and no x, dodge/stack/fill)
  are pixel-identical before and after.
- unit_tests/run.R: base-R checks (no testthat in the image) that build
  the bar layer and read back what ggplot computes: one bar per cell,
  stack order (crosstab order without x, x order with the colour on x),
  fill to 1, and plain ggplot behaviour when values share an x.
  Verified to fail on the 1.0.17 read order, the 1.0.18 no-x-only rule
  and an upside-down stack.
- .github/workflows/unit-tests.yml: builds the image and runs the tests
  in it on pull requests and pushes to master.
- README: how bar.position behaves, and how to run the tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fnaji
fnaji merged commit d0a6224 into master Oct 19, 2026
1 check passed
@fnaji
fnaji deleted the fix/bar-stack-x-order branch October 19, 2026 17:39
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.

1 participant