Conversation
Replace chart.js with Apache ECharts (modular build) to unlock chart
types chart.js can't do natively — starting with a contributor→language
treemap, with graph/sunburst/heatmap available for future work.
- echarts.ts: tree-shaken registration (line/bar/pie/treemap + grid,
tooltip, legend, title, canvas) mirroring the old chart.ts discipline
- theme.ts: registerEchartsTheme("repo") built from the CSS-var palette,
replacing the Chart.defaults block
- actions.ts: reusable `echart` Svelte action (init/setOption/resize/
dispose, onReady hands the instance to components)
- Port all six charts: weekly stacked-area line, commit-share pie,
add/del + net bars, contributor sparkline, hour/dow pattern bars
(click→popover via convertToPixel). Legend reset re-implemented with
legendselectchanged + dispatchAction(legendAllSelect)
- Non-interactive series use cursor:"default"; line series also silent
(its area ignores cursor); pattern bars pointer only when links on
- Remove chart.js; update README
Tradeoff: the single-file artifact grows 454 KB → 850 KB (raw, since it
is embedded un-gzipped). Accepted for the broader chart capability.
Title strips: - Move each chart's title out of the ECharts canvas into a blurred HTML overlay strip pinned to the top of the card (OverallCharts + PatternCard), so the canvas can scroll/zoom underneath and the title stays readable. - Shared .chart-title style (backdrop-filter blur, contributor colour for the pattern cards); shift chart grid/legend offsets to clear the strip. Languages-by-contributor treemap (treemap-show-parent layout): - Contributors are top-level containers: a full-width header strip in the contributor colour (centred name) with the colour also framing the container border and the gaps between language tiles. - Language tiles carry their own brand colour, with a half-transparent dark inner border for contrast against the contributor-coloured gaps. - Per-tile/header label colour flips near-white/near-black for contrast (new theme.ts contrastText helper + bgPrimary export). - Root background painted the card colour (was default white). - Tooltip only fires on language tiles (no ": 300%" on the root/containers). - Disable hover emphasis (no header re-layout jump) and override the treemap's forced pointer cursor to default (ECharts ignores series.cursor for treemap nodes). Rebuild dist/repo-intel.
- Pattern cards: drop the dashed axisPointer line on hover, make the whole column clickable (zrender + convertFromPixel) so the commit popover opens consistently rather than only on a pixel-perfect bar hit, and move the pointer cursor to the chart container. - Widen pattern cards to 380px so the hour/dow bars have more room. - Hide the "Languages by contributor" treemap when no contributor has any language data instead of rendering an empty chart.
- Debounce ResizeObserver resize via requestAnimationFrame (avoids resize loop warnings and thrash) - Guard private zrender display-list access in the treemap cursor hack so an ECharts upgrade degrades gracefully instead of throwing - Drop unused TitleComponent registration and dead title theme block (titles are CSS .chart-title overlays, not ECharts title:) - Treemap tooltip returns undefined (not "") for container nodes to fully suppress the empty tooltip box Rebuild dist/repo-intel.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (6)
📝 WalkthroughWalkthroughReplaces Chart.js with selective Apache ECharts setup, adds a reusable Svelte ChangesECharts Migration & repo data
Sequence Diagram(s)sequenceDiagram
participant Browser as Client
participant App as App.svelte
participant Theme as web/src/lib/theme.ts
participant EChartsMod as web/src/lib/echarts.ts
participant Action as web/src/lib/actions.ts (echart)
participant Component as Chart Component (Contributor/Overall/Pattern)
Browser->>App: load
App->>Theme: registerEchartsTheme()
Theme->>EChartsMod: register theme on echarts instance
Component->>Action: mount via use:echart(option, onReady)
Action->>EChartsMod: init chart (theme="repo"), setOption
Component->>Action: zrender events (click/legend) -> commit popover request
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
This repo has no ESLint setup (Bun workspace uses svelte-check + Prettier), so disabling the tool suppresses CodeRabbit's recurring "ESLint skipped" warning.
Surface repo composition alongside contributor stats: - File count at HEAD in the header subtitle, markdown report, and JSON - "Largest files (at HEAD)" treemap of uncompressed blob sizes - "Disk usage by path (full history)" treemap of compressed on-disk sizes summed per path, showing what fills the .git object store Both file-size views are computed on the local/bare-clone path; the remote GraphQL path has no per-file tree, so the fields stay null and the charts/markdown sections hide. Treemap chosen over sunburst because the size distribution is heavily skewed toward a few paths.
Swap the separate hour-of-day and day-of-week bar cards for a single ECharts scatter punch card per contributor: x=hour, y=weekday (Mon on top), dot size = commit count scaled per-card. Clicking a cell opens the commit-bucket popover labelled by the full cell (e.g. Friday 22:00-22:59). The punch card needs the joint hour x weekday distribution, which the old per-axis marginals can't reconstruct, so build it client-side from the commit list (buildPunchPoints, reusing isoBuckets). Drop the now-unused hourlyData/dowData from the Python output, types, and mock data; register ScatterChart; consolidate the two App sections and nav links into one.
Set the shared repo theme's tooltip background to --bg-popover (the same surface the body-portaled popovers use) so the default white tooltip box doesn't glare against the dark dashboard.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
repo-intel.py (1)
801-829: 💤 Low valuePotential memory pressure on very large repositories.
For repositories with massive histories (millions of objects), piping
rev-list --objects --allintocat-file --batch-checkloads the entire stdout into memory twice (revs.stdoutandcat.stdout). This is already O(history) as noted, but could exhaust memory on extremely large monorepos.Consider streaming the pipe if this becomes an issue, though for most repositories this approach is fine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@repo-intel.py` around lines 801 - 829, The current history_disk_by_path implementation captures the full output of `git rev-list ... --all` and `git cat-file --batch-check` into memory (revs.stdout and cat.stdout), which can OOM on very large repos; change this to stream the pipeline instead: replace the two subprocess.run calls with subprocess.Popen (or subprocess.run with stdin as a file-like stream) so that `git rev-list --objects --all` is started with stdout=PIPE and its stdout is passed directly as stdin to `git cat-file --batch-check`, then iterate over the resulting cat-file stdout as a file iterator to parse lines incrementally rather than storing cat.stdout; update references to revs, cat, and the line-parsing loop in history_disk_by_path accordingly and preserve the existing error handling behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@repo-intel.py`:
- Around line 801-829: The current history_disk_by_path implementation captures
the full output of `git rev-list ... --all` and `git cat-file --batch-check`
into memory (revs.stdout and cat.stdout), which can OOM on very large repos;
change this to stream the pipeline instead: replace the two subprocess.run calls
with subprocess.Popen (or subprocess.run with stdin as a file-like stream) so
that `git rev-list --objects --all` is started with stdout=PIPE and its stdout
is passed directly as stdin to `git cat-file --batch-check`, then iterate over
the resulting cat-file stdout as a file iterator to parse lines incrementally
rather than storing cat.stdout; update references to revs, cat, and the
line-parsing loop in history_disk_by_path accordingly and preserve the existing
error handling behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 39bc6b95-7dab-47f4-837c-076b640eadb5
⛔ Files ignored due to path filters (1)
dist/repo-intelis excluded by!**/dist/**
📒 Files selected for processing (16)
repo-intel.pyweb/public/mock-data.jsonweb/src/App.svelteweb/src/lib/actions.tsweb/src/lib/components/CommitPopover.svelteweb/src/lib/components/ContributorCard.svelteweb/src/lib/components/Header.svelteweb/src/lib/components/OverallCharts.svelteweb/src/lib/components/PatternCard.svelteweb/src/lib/echarts.tsweb/src/lib/format.tsweb/src/lib/popover-store.svelte.tsweb/src/lib/popovers.tsweb/src/lib/theme.tsweb/src/styles/app.cssweb/src/types.ts
💤 Files with no reviewable changes (1)
- web/src/lib/components/ContributorCard.svelte
✅ Files skipped from review due to trivial changes (2)
- web/src/lib/popover-store.svelte.ts
- web/src/lib/components/CommitPopover.svelte
Combine the HEAD and full-history "largest files" treemaps into a single
"Largest files" card with a HEAD / Full history tab toggle, keeping the
nested container-with-header layout.
Clicking a cell drills into its folder by re-rooting (dispatchAction
treemapRootToNode), which preserves the nested view while changing the
view root. A Svelte breadcrumb overlay (All › folder) and a top-left
Reset button navigate back; both are hidden at the root. The breadcrumb
is HTML rather than ECharts' built-in one so it can hide at root, sit
flush at the bottom, and avoid the canvas hit-region offset.
Also scope an override for the global `canvas { max-height: 300px }` rule
(.ec canvas { max-height: none }): it was crushing the 320px treemaps to
300px, so ECharts laid out hit-regions taller than the displayed canvas
and every hover/click landed below its tile.
- Colour file tiles by a single log-scaled grey ramp (brighter = larger) instead of the per-directory palette; folder headers are fixed dark chrome with a visible border so they read against the grey tiles. - Clicking drills one level toward the tile (a file zooms into its folder first); a click on a fully-zoomed leaf steps back out. Files are inert (default cursor); only folders carry the pointer. - Drop the redundant Reset button (click-to-zoom-out replaces it); keep the breadcrumb. - Inset the treemap below the title overlay so a zoomed-in folder's name strip isn't clipped.
Count distinct branches (union of local + remote-tracking heads, deduped) on local/bare paths and via GraphQL refs.totalCount on the remote path, thread it through build_data as branchCount, and render it in the header subtitle and the markdown report.
history_disk_by_path buffered the full rev-list object list and the cat-file output in memory, which can OOM on large repos. Pipe rev-list straight into cat-file and iterate the result line by line so neither the object list nor the size table is held in full at once.
head_file_sizes and history_disk_by_path decoded git output as strict UTF-8 under core.quotePath=false, so a single non-UTF-8 filename raised UnicodeDecodeError (not an OSError, so uncaught) and aborted the whole run. Read bytes and decode leniently, mirroring _head_first_line. The file-size treemap's grey scale included the 'N more files' remainder aggregate, pinning the bright end to a sum-of-many and washing every real file tile toward the dark floor. Exclude the remainder from the scale and clamp t so its off-scale tile still yields valid hex.
Summary
Replaces Chart.js with Apache ECharts (v6) across the dashboard, moving from per-canvas imperative chart construction to a single reusable
echartSvelte action (div mount →setOption→ auto-resize → dispose).What changed
echartaction (actions.ts): one home for the canvas→div mount model — init with the shared"repo"theme, re-apply options on update, ResizeObserver-driven resize, dispose on unmount.echarts.ts): only the series/components actually rendered are pulled in (line, bar, pie, treemap, scatter + grid/tooltip/legend), mirroring the oldchart.tstree-shaking discipline.theme.ts):registerEchartsTheme()replaces the oldChart.defaultsblock — palette, fonts, axis/grid colours read from CSS custom properties. Tooltips use the dark--bg-popoversurface so they match the body-portaled popovers.Commit-pattern punch card
The separate "Commit time patterns (hour of day)" bar chart and "Day of week patterns" bar chart are merged into a single scatter punch card per contributor: x = hour of day (0–23), y = weekday (Mon on top), dot size = commit count scaled per-card to that author's busiest cell. Clicking a cell opens the commit-bucket popover labelled by the full cell (e.g.
Friday 22:00–22:59).buildPunchPoints, reusing the timezone-safeisoBuckets).hourlyData/dowDataare dropped from the Python output,types.ts, and the mock data, trimming dead payload from every generated report.Review fixes
A best-practice review of the migration surfaced these, now applied:
ResizeObserver→chart.resize()throughrequestAnimationFrame(avoids resize-loop warnings/thrash).getZr().storage.getDisplayList()treemap-cursor access so a future ECharts bump degrades gracefully instead of throwing.TitleComponentregistration + deadtitletheme block (titles are CSS overlays).undefined(not"") for container nodes to fully suppress the empty tooltip box.Test plan
bun run check→ 0 errorsmake formatcleanmake buildregeneratesdist/repo-intel(committed; pre-commit hook keeps it in sync)Summary by CodeRabbit
New Features
Enhancement
Style
Documentation
Chore