Skip to content

feat(makie): implement flamegraph-basic#8511

Merged
MarkusNeusinger merged 6 commits into
mainfrom
implementation/flamegraph-basic/makie
Jun 8, 2026
Merged

feat(makie): implement flamegraph-basic#8511
MarkusNeusinger merged 6 commits into
mainfrom
implementation/flamegraph-basic/makie

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Implementation: flamegraph-basic - julia/makie

Implements the julia/makie version of flamegraph-basic.

File: plots/flamegraph-basic/implementations/julia/makie.jl

Parent Issue: #4665


🤖 impl-generate workflow

@claude

claude Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 1/3

Image Description

Light render (plot-light.png): Warm off-white #FAF8F1 background. Title "CPU Profile of a Web Request Handler · flamegraph-basic · julia · makie · anyplot.ai" in dark ink, auto-scaled to ~16pt (the title exceeds the 67-char threshold so the implementation downsizes it cleanly). X-axis label "Proportion of CPU samples" + percentage ticks (0%-100%) in dark/soft ink, all sharply readable. Y-axis label "Stack depth (caller → callee)" rotated in soft ink; y-ticks/labels intentionally hidden (depth is shown by stacking). Only the bottom spine remains; no grid. Seven stack-depth rows, root 'main' at the bottom spanning 0-100% with 'server.handle_request'/'runtime.gc' above, then 'app.route'/'walk_heap', narrowing toward the leaves. Bars colored from the warm Imprint subset (amber #DDCC77, ochre #BD8233, matte-red #AE3030) — brand green sits out by design. Hairline page-bg strokes separate adjacent siblings. In-bar function-name labels only appear where the bar is wide enough — all chrome readable; in-bar dark text is comfortable on amber/ochre, weaker but still legible on the red bars.

Dark render (plot-dark.png): Warm near-black #1A1A17 background. Every chrome element — title, axis labels, ticks, spine — flipped correctly via theme tokens to light ink (~#F0EFE8 / soft variant). No dark-on-dark chrome anywhere. Bar fill colors are byte-identical to the light render (same amber/ochre/red), exactly as required (only chrome flips). The hairline separators now read as dark slits between same-color sibling bars (PAGE_BG is dark in this theme), still working structurally. In-bar labels remain dark ink intentionally — the bars are warm-colored, so dark labels on amber/ochre are fine; dark labels on the red bars have the same weak contrast as in the light render (a global polish opportunity, not a theme-adaptation failure).

Score: 87/100

Category Score Max
Visual Quality 28 30
Design Excellence 13 20
Spec Compliance 15 15
Data Quality 15 15
Code Quality 10 10
Library Mastery 6 10
Total 87 100

Visual Quality (28/30)

  • VQ-01: Text Legibility (7/8) — chrome fully readable in both themes; in-bar dark labels on matte-red bars are at the edge of comfortable contrast
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (6/6)
  • VQ-04: Color Accessibility (1/2) — warm-only palette is spec-mandated; luminance differences help CVD viewers but red-green axis isn't ideal
  • VQ-05: Layout & Canvas (4/4) — 3200×1800 landscape, canvas gate passed
  • VQ-06: Axis Labels & Title (2/2)
  • VQ-07: Palette Compliance (2/2) — semantic-exception subset of Imprint, explicitly grounded in the spec's "warm flame palette" rule

Design Excellence (13/20)

  • DE-01: Aesthetic Sophistication (5/8) — custom warm subset, intentional restraint, clean theme tokens
  • DE-02: Visual Refinement (5/6) — top/right/left spines off, grid off, y-ticks off, hairline separators — strong minimal-chrome discipline
  • DE-03: Data Storytelling (3/6) — flame shape inherently shows the hot path, but no extra emphasis on the dominant db.fetch_rows leaf

Spec Compliance (15/15)

  • SC-01: Plot Type (5/5) — textbook Brendan-Gregg flame graph, root at bottom, callees stacked upward, alphabetical sibling order
  • SC-02: Required Features (4/4) — width ∝ samples, bottom-up caller→callee, in-bar labels when wide enough, warm palette, adjacent bars with hairline separation
  • SC-03: Data Mapping (3/3) — X = proportion of CPU samples (0-100%), Y = stack depth
  • SC-04: Title & Legend (3/3) — {Descriptive} · flamegraph-basic · julia · makie · anyplot.ai; no legend needed

Data Quality (15/15)

  • DQ-01: Feature Coverage (6/6) — 7-deep stacks, wide leaves, narrow leaves, gc + epoll branches
  • DQ-02: Realistic Context (5/5) — web request handler CPU profile, plausible and neutral
  • DQ-03: Appropriate Scale (4/4) — sample counts 5–86, total ~450, proportions sensible

Code Quality (10/10)

  • CQ-01: KISS Structure (3/3) — top-level script, iterative DFS instead of recursion
  • CQ-02: Reproducibility (2/2) — Random.seed!(42), hardcoded profile
  • CQ-03: Clean Imports (2/2) — CairoMakie, Colors, Random all used
  • CQ-04: Code Elegance (2/2) — clear sections, no fake interactivity
  • CQ-05: Output & API (1/1) — plot-$(THEME).png via save(..., px_per_unit=2)

Library Mastery (6/10)

  • LM-01: Idiomatic Usage (4/5) — batched poly! with Vector{Rect2f} + per-rectangle colors, correct Figure/Axis config
  • LM-02: Distinctive Features (2/5) — no GridLayout composition, no Theme(), no Observable, no recipe — modest above the default

Score Caps Applied

  • None

Strengths

  • Correct flame-graph topology: root 'main' at bottom, callees stacked upward, widths proportional to aggregated samples — reads as a textbook Brendan-Gregg flame graph.
  • Semantic-exception palette is well-grounded: warm subset of Imprint (#DDCC77 amber, #BD8233 ochre, #AE3030 red) keeps the conventional flame aesthetic without inventing colors outside the brand palette, and a comment explains why brand green sits out.
  • Theme tokens are threaded cleanly through every chrome element (title/labels/ticks/spine); both renders fully legible; data colors byte-identical across themes as required.
  • Iterative DFS layout keeps the script top-level (no recursive helper function) while still producing a deterministic alphabetical sibling order — KISS done right.
  • Minimal chrome is intentional: top/right/left spines removed, grid removed, y-ticks/labels removed (depth is conveyed by stacking position).
  • In-bar label gating ('only draw when bar width ≥ text width') prevents the classic flame-graph text-overflow mess at narrow stacks.
  • Hairline page-background strokes between sibling rectangles cleanly separate adjacent same-color bars without visible gaps.
  • Idiomatic batched CairoMakie usage: single poly! call with a vector of Rect2f and per-rectangle fill colors instead of looping rect-by-rect.

Weaknesses

  • In-bar text color is hardcoded to colorant"#1A1A17" (dark ink). On amber/ochre bars contrast is fine, but on the matte-red #AE3030 bars (e.g. 'app.route', 'server.handle_request', 'product_handler') dark-on-dark-red contrast is noticeably weak in both themes. A luminance-aware label color (dark ink on amber/ochre, light ink #FAF8F1 on red) would lift VQ-01 to full marks.
  • DE-03 storytelling is limited to what the flame shape conveys — no extra emphasis on the dominant hot path (db.fetch_rows ≈ 24% of total). A subtle accent or annotation on the largest leaf could promote a focal point without breaking the convention.
  • LM-02 distinctive Makie features are modest: no Theme(), no GridLayout composition, no Observable, no recipe. A Theme() block holding the chrome tokens, or a small inset Axis showing per-depth sample totals, would showcase more of Makie's vocabulary.
  • Color assignment via abs(hash(name)) % 3 is stable but semantically arbitrary — adjacent siblings can land on the same color, slightly muting the 'distinct child' signal. Assigning color by depth (or by child index within a parent) would give a more readable color rhythm; minor DE-01/VQ-03 polish.

Issues Found

  1. VQ-01 NICK: Dark in-bar labels on matte-red bars have weak contrast.
    • Fix: pick the label color per bar by luminance — dark ink on amber/ochre, light ink on red.
  2. DE-03 LOW: No focal-point emphasis on the dominant hot path.
    • Fix: add a subtle outline or short annotation on the widest leaf at the top of the stack (e.g. db.fetch_rows).
  3. LM-02 LOW: Distinctive Makie features modest.
    • Fix: hoist chrome tokens into a Theme(), or add an inset Axis showing aggregate samples per depth.

AI Feedback for Next Attempt

Strong, ships-as-is. The two highest-leverage improvements: (1) luminance-aware in-bar label color so red bars get light text — this is the only legibility issue across both renders, and (2) add a focal-point cue (outline / annotation) on the dominant db.fetch_rows leaf to lift storytelling. A Theme() block holding the chrome tokens would also showcase more Makie-native vocabulary for LM-02.

Verdict: APPROVED

@github-actions github-actions Bot added quality:87 Quality score 87/100 ai-rejected Quality not OK, triggers update labels Jun 8, 2026
@github-actions github-actions Bot added ai-attempt-1 First repair attempt and removed ai-rejected Quality not OK, triggers update labels Jun 8, 2026
Attempt 1/3 - fixes based on AI review

- VQ-01: luminance-aware in-bar label color (dark ink on amber/ochre,
  light ink on red) so the matte-red bars get readable contrast
- DE-03: focal-point cue on the dominant hot-path leaf (db.fetch_rows,
  19% of CPU) — thicker INK outline plus a short annotation above it
- LM-02: hoist chrome tokens into a Theme() block for more idiomatic
  Makie styling vocabulary
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

🔧 Repair Attempt 1/4

Applied fixes based on AI review feedback.

Status: Repair completed, re-triggering review...


🤖 impl-repair

@claude

claude Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

AI Review - Attempt 2/3

Image Description

Light render (plot-light.png): Warm off-white #FAF8F1 background. Title "CPU Profile of a Web Request Handler · flamegraph-basic · julia · makie · anyplot.ai" in dark INK at top, x-label "Proportion of CPU samples" and rotated y-label "Stack depth (caller → callee)" both in dark INK, x-tick labels (0%, 20%, 40%, 60%, 80%, 100%) in INK_SOFT mid-gray. Bottom spine only; no grid. Stacked flame bars in the warm Imprint subset — amber #DDCC77, ochre #BD8233 (Imprint #4), matte red #AE3030 (Imprint #5). Bottom row "main" spans the full width in amber; "server.handle_request" and "runtime.gc" sit one row up; the dominant db.fetch_rows leaf on the right side of row 5 carries a thick black INK outline plus a "▼ hot path · 19% of CPU samples" caption. In-bar function-name labels are dark on amber/ochre, light on matte-red, all readable. All text legible against the light background.

Dark render (plot-dark.png): Warm near-black #1A1A17 background. Same title now in light INK #F0EFE8, same axis labels and tick labels in light INK / INK_SOFT — no dark-on-dark failures. Data fills are identical to the light render (amber / ochre / matte red — Imprint identity preserved across themes). Hot-path outline correctly flips to light INK so it reads on the dark surface. Hot-path caption visible. All text clearly readable.

Score: 88/100

Category Score Max
Visual Quality 30 30
Design Excellence 16 20
Spec Compliance 14 15
Data Quality 13 15
Code Quality 9 10
Library Mastery 7 10
Total 88 100

Visual Quality (30/30)

  • VQ-01: Text Legibility (8/8)
  • VQ-02: No Overlap (6/6)
  • VQ-03: Element Visibility (6/6)
  • VQ-04: Color Accessibility (2/2)
  • VQ-05: Layout & Canvas (4/4)
  • VQ-06: Axis Labels & Title (2/2)
  • VQ-07: Palette Compliance (2/2) — Imprint members only; brand-green opt-out properly justified by the spec's warm-flame-aesthetic note

Design Excellence (16/20)

  • DE-01: Aesthetic Sophistication (6/8) — Theme tokens hoisted, luminance-driven label ink, focal-point cue
  • DE-02: Visual Refinement (5/6) — spines and y-ticks suppressed, no grid
  • DE-03: Data Storytelling (5/6) — hot-path outline + caption gives a clear focal point

Spec Compliance (14/15)

  • SC-01: Plot Type (5/5)
  • SC-02: Required Features (3/4) — data size (20 traces) falls short of spec's 50-500 range
  • SC-03: Data Mapping (3/3)
  • SC-04: Title & Legend (3/3)

Data Quality (13/15)

  • DQ-01: Feature Coverage (4/6) — limited richness: 20 traces vs spec 50-500
  • DQ-02: Realistic Context (5/5) — plausible web-request profile, neutral
  • DQ-03: Appropriate Scale (4/4)

Code Quality (9/10)

  • CQ-01: KISS Structure (2/3) — contrast_ink helper introduces a small abstraction for a 3-element array
  • CQ-02: Reproducibility (2/2)
  • CQ-03: Clean Imports (2/2)
  • CQ-04: Code Elegance (2/2) — iterative DFS layout avoids recursion
  • CQ-05: Output & API (1/1)

Library Mastery (7/10)

  • LM-01: Idiomatic Usage (4/5) — Theme() block, Axis kwargs, vectorized poly!(rects; color=array)
  • LM-02: Distinctive Features (3/5) — no standout Makie-only feature

Score Caps Applied

  • None

Strengths

  • Theme tokens hoisted into a single Theme() block — chrome flips cleanly between renders with no element left behind.
  • Hot-path focal cue (thick INK outline on the dominant db.fetch_rows leaf + "▼ hot path · 19% of CPU samples" caption) directs the eye without breaking the flame aesthetic.
  • Warm flame palette uses Imprint members only (#DDCC77 amber anchor, #BD8233 Imprint feat: add complete automation infrastructure for plot generation #4, #AE3030 Imprint #5), and the code explicitly documents the brand-green opt-out as a spec-driven semantic exception.
  • Luminance-based label ink (contrast_ink) keeps function-name labels readable on every fill: dark on amber/ochre, light on matte-red.
  • Hairline PAGE_BG stroke between sibling rectangles separates same-color neighbours without competing with the data.
  • Title-length adaptive sizing (round(20 × 67 / len(title))) handles the long descriptive-prefix title on the landscape canvas without overflow.

Weaknesses

  • Profile contains only 20 unique stack traces; spec asks for 50-500 — well below the lower bound. Extend the synthetic profile (more siblings at depths 3-5, more leaves) so the chart density matches the spec's intended scale.
  • contrast_ink(c) helper is the only top-level function in the script and slightly bends CQ-01 KISS. Consider inlining the result since FLAME_COLORS has only 3 entries.
  • LM-02 ceiling: vectorized poly! + Theme() block are idiomatic but not distinctive. Consider a Makie-specific touch such as a Colorbar tied to value or arrow annotation!s locked to data coordinates.

Issues Found

  1. DQ-01 / SC-02 LOW: Profile has 20 stack traces vs spec's 50-500 range
    • Fix: Expand the profile vector with more nested call paths and leaves — aim for 60-120 unique traces so the flame fills out more densely.
  2. CQ-01 LOW: One top-level helper function bends KISS
    • Fix: Inline FLAME_LABEL_INK as a 3-element literal alongside FLAME_COLORS and drop contrast_ink.

AI Feedback for Next Attempt

Expand the synthetic profile to 60-120 unique stack traces (still a believable web-request workload) so the chart visually reflects the spec's data-scale ask. Inline the label-ink choice and remove contrast_ink. Consider one Makie-distinctive touch — for instance, a vertical INK_SOFT reference line at the cumulative 50% mark with a small inline annotation — to push LM-02 higher without disturbing the flame aesthetic.

Verdict: APPROVED

@github-actions github-actions Bot added quality:88 Quality score: 88/100 ai-approved Quality OK, ready for merge and removed quality:87 Quality score 87/100 labels Jun 8, 2026
@MarkusNeusinger MarkusNeusinger merged commit cfbe2d2 into main Jun 8, 2026
3 checks passed
@MarkusNeusinger MarkusNeusinger deleted the implementation/flamegraph-basic/makie branch June 8, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-approved Quality OK, ready for merge ai-attempt-1 First repair attempt quality:88 Quality score: 88/100

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant