feat(vegalite): add Calendar Heatmap template#64
Open
zl190 wants to merge 2 commits into
Open
Conversation
Port the Calendar Heatmap to the Vega-Lite backend, mirroring the ECharts implementation (ecCalendarHeatmapDef). ECharts uses a first-class calendar coordinate system; Vega-Lite has none, but it needs no computed week/day fields either — timeUnit expresses the GitHub-style grid from a single date field: yearweek on x (one ordinal column per calendar week), day on y (Sun–Sat rows, Monday-first to match the ECharts dayLabel), and sum on color collapses rows sharing a calendar day into one cell. The upstream ECharts calendar.ts header notes VL "has no first-class calendar; would fake it with rect + computed week/day fields" — timeUnit avoids the computed fields, so no core changes are needed. Scheme handling mirrors the ECharts template's encodingActions: named Vega-Lite schemes (viridis/blues/greens/reds/oranges/purples) pass through as scale.scheme; "github" has no built-in Vega-Lite equivalent, so it resolves to an explicit scale.range (the same low→high ramp the ECharts template uses). - register in vlTemplateDefs (Tables & Maps group, next to Heatmap) - tests: 8 cases (registry, dual-axis timeUnit projection, Monday-first row order, per-day sum, count fallback, github range vs named scheme, cross-backend parity); assembled spec also verified through vl.compile - docs: regenerate reference-vegalite.md; move Calendar Heatmap from the SKILL.md "ECharts adds" list into the shared template table (+ synced bundled asset) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The `github` scheme now maps counts through a quantile scale (equal-count bins → the 5 canonical GitHub buckets) instead of a continuous ramp, so a Calendar Heatmap with `color.scheme: 'github'` renders the discrete, snapped levels people recognize from the GitHub contribution graph. Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.
What
Adds a Calendar Heatmap template to the Vega-Lite backend, bringing it to
parity with the ECharts backend (
ecCalendarHeatmapDef).ECharts has a first-class
calendarcoordinate system; Vega-Lite has none. TheECharts
calendar.tsheader notes that VL "has no first-class calendar; wouldfake it with rect + computed week/day fields." It turns out no computed fields
are needed —
timeUnitexpresses the GitHub-style grid directly from a singledate field:
timeUnit: 'yearweek'(one ordinal column per calendar week)timeUnit: 'day'(Sun–Sat rows, Monday-first to match the EChartsdayLabel.firstDay = 1)aggregate: 'sum'collapses rows sharing a calendar day into one cellso the same date field drives both axes with no core changes.
Encoding
x(date)color(quantitative)Scheme handling
Mirrors the ECharts template's
encodingActions: named Vega-Lite schemes(
viridis/blues/greens/reds/oranges/purples) pass through asscale.scheme;githubhas no built-in Vega-Lite equivalent, so it resolves toan explicit
scale.range(the same low→high ramp the ECharts template uses).Changes
vegalite/templates/calendar.ts— newvlCalendarHeatmapDefvlTemplateDefs(Tables & Maps group, next to Heatmap)tests/calendar-vegalite.test.ts— 8 cases: registry, dual-axistimeUnitprojection, Monday-first row order, per-day sum, count fallback,
githubrange vs named scheme, and cross-backend parity. The assembled spec is also
verified through
vl.compile.docs/reference-vegalite.md; move Calendar Heatmap from theSKILL.md "ECharts adds" list into the shared template table (+ synced bundled
asset)
Open questions
shipped ECharts calendar (
dayLabel.firstDay = 1), so the same spec renders thesame way on both backends. This differs from GitHub's own contribution graph,
which starts the week on Sunday. I kept parity with the existing backend rather
than mirroring GitHub. If you'd rather the canonical calendar follow GitHub
(Sunday-first), that's a cross-backend convention change — ECharts and Vega-Lite
together — which I'm happy to do as a separate PR so the two backends stay aligned.
yearweekproduces a continuous band that widens withrange; the ECharts template shrinks its cell size instead. This PR relies on
labelOverlap+ the container width. Happy to add explicit cell sizing if youprefer.
temporal
x+ quantitativecolorheuristic). Let me know if you'd like one.