Repository navigation
Conversation
yhoonkim
force-pushed
the
fix/tick-timeunit-band-position-with-size
branch
from
April 21, 2026 22:42
78f2042 to
8988779
Compare
kanitw
approved these changes
Apr 21, 2026
kanitw
reviewed
Apr 21, 2026
kanitw
approved these changes
Apr 21, 2026
Contributor
|
Great to see this getting fixed, thank you! There is a somewhat related PR in #9827 which tries to address the fact that |
yhoonkim
force-pushed
the
fix/tick-timeunit-band-position-with-size
branch
from
April 22, 2026 15:59
8988779 to
9227650
Compare
β¦size`
In `positionAndSize`, the center ref used a hardcoded `bandPosition` of 0.5,
so `config.tick.timeUnitBandPosition` (and `bandPosition` on a timeUnit
field) was silently ignored whenever an explicit `size` forced the
tick/rect code path. This misaligned the tick from a bar sharing the same
`timeUnitBandPosition` config.
Derive `bandPosition` via `getBandPosition({fieldDef, markDef, config})`
when the field has a `timeUnit` and no secondary channel def, matching
the behavior of `rectBinPosition`.
Fixes vega#9836
yhoonkim
force-pushed
the
fix/tick-timeunit-band-position-with-size
branch
from
April 22, 2026 17:31
9227650 to
d8656c6
Compare
5 tasks done
Contributor
Author
kanitw
pushed a commit
that referenced
this pull request
Apr 23, 2026
β¦size` (#9838) ## PR Description Fixes #9836. > Re-opened from #9837 with the branch pushed directly to this repo so CI > has full access. Previously reviewed and approved by @kanitw in #9837; > review feedback (extract `bandPosition` to a local const with `??`) is > already folded in, along with added tests that cover the three > branches flagged by codecov's patch check. When a `tick` (or rect-based) mark has an explicit `size` and its `x`/`y` encoding uses a `timeUnit` field, `config.<mark>.timeUnitBandPosition` β and `bandPosition` set on the field β were silently ignored. The tick was always centered at the bin midpoint, which misaligned it with a `bar` on the same encoding when e.g. `timeUnitBandPosition: 0` was configured. ### Root cause `rectPosition` (in `src/compile/mark/encode/position-rect.ts`) dispatches to two branches: - `rectBinPosition` β honors `timeUnitBandPosition` via `getBandPosition`, and routes through the `*_offsetted_rect_start/end` fields. - `positionAndSize` β used when `size` is set; hardcoded `bandPosition` to `0.5` for the center ref (`xc`/`yc`) and never consulted `fieldDef.timeUnit` or `getBandPosition({fieldDef, ...})`. So the second path produced `xc: scale("x", 0.5 * datum["date"] + 0.5 * datum["date_end"])` regardless of the configured band position. ### Fix In `positionAndSize`, when the channel has a `timeUnit` field and no secondary channel def, derive `bandPosition` via the same `getBandPosition({fieldDef, markDef, config})` helper used by `rectBinPosition`, and pass it through to `midPointRefWithPositionInvalidTest`. With `bandPosition: 0`, `interpolatedSignalRef` short-circuits to `{scale: 'x', field: <startField>}`, placing the tick's center on the bin start β matching the bar's center under the same config. ### Verification - New example `layer_bar_tick_binned_time_band_position.vl.json` β first commit adds it with the broken rendering, second commit applies the fix and updates the compiled output so the diff shows the visual improvement. - Unit tests in `test/compile/mark/encode/position-rect.test.ts` cover the fix plus the three fallback branches in the refactored expression (for patch coverage). - Full unit suite passes locally. <details> <summary><h2>Checklist</h2></summary> - [x] This PR is atomic (i.e., it fixes one issue at a time). - [x] The title is a concise [semantic commit message](https://www.conventionalcommits.org/). - [x] `npm test` runs successfully. - For new features: - [x] Has unit tests. - [x] Has documentation under `site/docs/` + examples. _(bug fix, no docs needed)_ </details> --------- Co-authored-by: GitHub Actions Bot <vega-actions-bot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Description
Fixes #9836.
When a
tick(or rect-based) mark has an explicitsizeand itsx/yencoding uses a
timeUnitfield,config.<mark>.timeUnitBandPositionβand
bandPositionset on the field β were silently ignored. The tick wasalways centered at the bin midpoint, which misaligned it with a
baronthe same encoding when e.g.
timeUnitBandPosition: 0was configured.Root cause
rectPosition(insrc/compile/mark/encode/position-rect.ts) dispatchesto two branches:
rectBinPositionβ honorstimeUnitBandPositionviagetBandPosition,and routes through the
*_offsetted_rect_start/endfields.positionAndSizeβ used whensizeis set; hardcodedbandPositionto0.5for the center ref (xc/yc) and never consultedfieldDef.timeUnitorgetBandPosition({fieldDef, ...}).So the second path produced
xc: scale("x", 0.5 * datum["date"] + 0.5 * datum["date_end"])regardless of the configured band position.Fix
In
positionAndSize, when the channel has atimeUnitfield and nosecondary channel def, derive
bandPositionvia the samegetBandPosition({fieldDef, markDef, config})helper used byrectBinPosition, and pass it through tomidPointRefWithPositionInvalidTest.With
bandPosition: 0,interpolatedSignalRefshort-circuits to{scale: 'x', field: <startField>}, placing the tick's center on the binstart β matching the bar's center under the same config.
Verification
test/compile/mark/encode/position-rect.test.tscovering tick + explicit
size+timeUnitBandPosition: 0.xc: {scale: "x", field: "date"}, aligned with the bar.Checklist
npm testruns successfully.site/docs/+ examples. (bug fix, no docs needed)