posit-dev / posit-dev/ggsql

Free facet dimensions get the globally resolved breaks, so most panels show one tick

Open
#516 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

plot building writer
Dominant language
Rust
Stars
554
Forks
30
Avg merge
17h 27m
Merged PRs (30d)
8

Description

Summary

ggsql resolves exactly one scale — and one break set — per aesthetic, including for a facet dimension declared free. The Vega-Lite writer therefore pins the global break set as axis.values even where it has delegated the domain to Vega, so each free panel shows only whichever global breaks happen to fall inside it — frequently one, or none.

While this issue is about the breaks specifically, it also points to a deficiency in our ggsql <-> writer contract. Specifically for faceted plots with free scales we are currently letting the writer calculate range, breaks etc for the free scales. This really belongs in ggsql which should resolve the scale to an array somehow (VegaLite might not be able to consume that but Hephaestus can)

Reproduction
VISUALISE Date AS x, Temp AS y FROM ggsql:airquality
DRAW line
FACET Month SETTING free => 'x'
resolve: {'scale': {'x': 'independent'}}     # domain correctly delegated to Vega
scale:   {'zero': False}                     # no domain, as intended
values:  ['1973-04-23', '1973-05-21', '1973-06-18', '1973-07-16', '1973-08-13', '1973-09-10']

Those six breaks span the whole year, but each panel covers one month — so a panel gets at most one of them.

Why it belongs in core

Both writers currently work around the missing per-panel resolution, in different places and with different results:

  • Vega-Lite delegates the domain to Vega (resolve.scale: independent) but still pins global break values on top of it.
  • hephaestus computes the per-panel extent itself in scales::free_position_scale / free_binned_scale, applying ggsql's own Scale::expand_range factors — this is the one remaining piece of writer-side domain computation, and it exists solely because core resolves nothing per panel.

Resolving per-panel domains and breaks for a free facet dimension in core fixes the Vega-Lite tick problem and removes the hephaestus writer's architectural exception in one go.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the facet reproduction and inspect how ggsql resolves scales and breaks for free dimensions. Read the Vega-Lite writer's handling of resolve.scale and axis.values, then compare hephaestus's scales::free_position_scale, free_binned_scale, and Scale::expand_range. Done means core provides per-panel domains and breaks so writers no longer apply global breaks or compute free extents themselves.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
data-visualization
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.