بنقرة واحدة
data-reports
Data visualization report scripts. NOT for general ETL or scraping (use data).
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Data visualization report scripts. NOT for general ETL or scraping (use data).
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Development wisdom and workflow rules. NOT for project-specific conventions (those live in CLAUDE.md, edit via wisdom).
The `BUGS.md` open-issues queue — entry format, lifecycle, pruning to diary. NOT for the record-don't-fix policy (that's CLAUDE.md Bug Triage Protocol), NOT for resolved-bug history (use /diary), NOT for feature backlog (use TODO.md/specs).
Terminal demo GIF + MP4 recordings for READMEs and social (asciinema + agg + ffmpeg). NOT for general Makefile targets (use software) or GUI screenshots (use visual).
Go development. NOT for non-Go code (use rs, py, ts, tsx, or sh).
Humanize text: strip AI-isms and add real voice. NOT for drafting new copy (use writing).
Python development. NOT for shell scripting (use sh) or non-Python code.
| name | data-reports |
| description | Data visualization report scripts. NOT for general ETL or scraping (use data). |
| when_to_use | Vega-Lite charts, report generator, chart script, multi-panel PNG, structured data visualization, Bun report script, data presentation script |
Reference example: scripts/report-chart.ts (validator-bonds).
bun runtime, vega-lite (spec), vega (render), sharp (SVG→PNG), yaml (input).compile(spec).spec → vega.parse → new vega.View(parsed, {renderer:'none'}) → await view.toSVG() → sharp(Buffer.from(svg)).png().toFile(out).Bun.spawn + await proc.exited — NEVER Bun.spawnSync.[report.yml] [out.png] with defaults (out = report with .png). -h/--help writes usage to stderr, then process.exit(2).load() — read YAML, map to typed row objects, derive computed fields there (e.g. actualFeeBps = feeAdj * maxFeeBps / feeMax). NEVER compute in the spec.loadConfigTarget() — read sibling config (e.g. settlement-config.yaml) for reference lines; return null if missing so the chart still renders without the target line.async function main() — all chart math, spec construction, render.title.text = what + range (e.g. '… Simulation · Epochs 885–985').title.subtitle = the run SETUP so the chart is self-describing: input tag + key config bounds (e.g. 'r200-x1600 · min fee 200 bps · max fee 1600 bps'). Derive the tag from the input filename basename (<tag>.yml → <tag>; suppress the bare default report). Style with subtitleFontSize: 11, subtitleColor: '#666'.Panels stacked in vconcat; hconcat for side-by-side pairs.
height: 20, invisible mark, legend.orient: 'top') — separates legend from the panel above.hconcat of two half-width panels (e.g. 460 each).height: 1, type:'text' mark) — config params + source file.[brackets] in axis and panel titles: 'Fee Payable [SOL]', 'fee [%]', 'APY [%]'. ALWAYS name the quantity before the unit — '[SOL]' alone is not enough; write 'Fee Payable [SOL]' or 'Stake [SOL]'.Math.ceil(max * 1.1 / 100) * 100; SOL → Math.ceil(max * 1.1 / 10) * 10.range(lo, hi) → scale: { domain: epochDomain }, so missing slots stay visible instead of collapsing.mkLabel(s) helper → s > 1 ? \...% ${s} === 0...` : 'datum.label'. Full-width panel (960px): mkLabel(Math.ceil(n/40)). Half-width panels (460px): double the stride → xEncSmall = { ...xEnc, axis: { ...xEnc.axis, labelExpr: mkLabel(stride*2) } }`.offset: all lower panels 4 (tight); dedicated legend row (owns its row) uses 0.'adjusted', 'at max fee', 'at min fee', 'max-fee cap'. Acronyms only: keep uppercase (e.g. 'SSR baseline').resolve: { scale: { color: 'independent' } } on the top level AND on any hconcat panel with its own color encoding.Date.now() (which mislabels historical reports): a boundary period holding fewer epochs than its neighbour is partial → cnt(0) < cnt(1) and cnt(last) < cnt(last-1). Factor fillOpacity/strokeWidth/strokeDash conditionals into a hollowBar object, spread into the bar layer's encoding. Incomplete = fillOpacity:0, strokeWidth:1.5, strokeDash:[4,2].rule mark at { datum: target } for the line itself.text mark pinned to an edge, NEVER centered: left edge → x: { value: 0 }, align: 'left', dx: 4; right edge → x: { value: width }, align: 'right'.rule mark plus a rotated text label.Define as top-of-file constants:
C_ACTUAL = '#4682b4' (blue — actual/observed)C_REF = '#708090' (gray — reference line)C_CAP = '#2e8b57' (green — cap/ceiling)C_MINFEE = '#9370db' (purple — floor/min)C_COST = '#b22222' (red — cost/risk/shortfall)(unit) in labels — ALWAYS [unit] (so [SOL], not (SOL)). NEVER use bare [unit] as an axis title — always prepend the quantity name.align + x: { value }.Bun.spawnSync — ALWAYS Bun.spawn + await .exited.load().