From b90f72b22c7938014f2f946c23e4bd7871913d6c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 25 Jul 2026 23:55:48 +0000 Subject: [PATCH 1/5] feat(makie): implement slope-basic Co-Authored-By: Claude Sonnet 5 --- .../implementations/julia/makie.jl | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 plots/slope-basic/implementations/julia/makie.jl diff --git a/plots/slope-basic/implementations/julia/makie.jl b/plots/slope-basic/implementations/julia/makie.jl new file mode 100644 index 0000000000..c13aecac4a --- /dev/null +++ b/plots/slope-basic/implementations/julia/makie.jl @@ -0,0 +1,128 @@ +# anyplot.ai +# slope-basic: Basic Slope Chart (Slopegraph) +# Library: Makie.jl 0.22 | Julia 1.11 +# Quality: pending | Created: 2026-07-25 + +using CairoMakie +using Colors +using Random + +Random.seed!(42) + +# --- Theme tokens ------------------------------------------------------- +THEME = get(ENV, "ANYPLOT_THEME", "light") +PAGE_BG = THEME == "light" ? colorant"#FAF8F1" : colorant"#1A1A17" +INK = THEME == "light" ? colorant"#1A1A17" : colorant"#F0EFE8" +INK_SOFT = THEME == "light" ? colorant"#4A4A44" : colorant"#B8B7B0" + +IMPRINT_INCREASE = colorant"#009E73" # brand green — gain (semantic exception: positive change) +IMPRINT_DECREASE = colorant"#AE3030" # matte red — loss (semantic exception: negative change) + +# --- Data ---------------------------------------------------------------- +# Customer satisfaction score (0-100) for 10 product lines, comparing the +# 2023 and 2024 annual surveys. +products = [ + "Cloud Storage", "Mobile App", "Analytics Suite", "Payment Gateway", + "Support Chat", "API Platform", "Video Conferencing", "Data Backup", + "Email Client", "Customer Portal", +] +n = length(products) +score_2023 = round.(rand(n) .* 35 .+ 48, digits=1) +change = round.(randn(n) .* 8, digits=1) +score_2024 = round.(clamp.(score_2023 .+ change, 0, 100), digits=1) + +order = sortperm(score_2023, rev=true) +products, score_2023, score_2024 = products[order], score_2023[order], score_2024[order] + +y_min, y_max = minimum(vcat(score_2023, score_2024)), maximum(vcat(score_2023, score_2024)) +y_pad = (y_max - y_min) * 0.12 +ylim_lo, ylim_hi = y_min - y_pad, y_max + y_pad * 2.2 + +# Nudge label y-positions apart (independent of true marker/line position) +# so entity names don't overlap when two scores land close together. +min_gap = (ylim_hi - ylim_lo) * 0.052 + +label_y_left = copy(score_2023) +left_order = sortperm(label_y_left) +for _ in 1:200 + moved = false + for k in 1:(n - 1) + i, j = left_order[k], left_order[k + 1] + if label_y_left[j] - label_y_left[i] < min_gap + center = (label_y_left[i] + label_y_left[j]) / 2 + label_y_left[i] = center - min_gap / 2 + label_y_left[j] = center + min_gap / 2 + moved = true + end + end + moved || break +end + +label_y_right = copy(score_2024) +right_order = sortperm(label_y_right) +for _ in 1:200 + moved = false + for k in 1:(n - 1) + i, j = right_order[k], right_order[k + 1] + if label_y_right[j] - label_y_right[i] < min_gap + center = (label_y_right[i] + label_y_right[j]) / 2 + label_y_right[i] = center - min_gap / 2 + label_y_right[j] = center + min_gap / 2 + moved = true + end + end + moved || break +end + +# --- Plot ------------------------------------------------------------------ +fig = Figure( + resolution = (1600, 900), + fontsize = 14, + backgroundcolor = PAGE_BG, +) + +title_text = "slope-basic · julia · makie · anyplot.ai" + +ax = Axis( + fig[1, 1]; + title = title_text, + titlesize = 20, + titlecolor = INK, + backgroundcolor = PAGE_BG, +) +hidedecorations!(ax) +hidespines!(ax) +xlims!(ax, -0.85, 1.85) +ylims!(ax, ylim_lo, ylim_hi) + +# The two vertical reference axes, one per survey year +vlines!(ax, [0, 1]; color=INK_SOFT, linewidth=1.5) + +for i in 1:n + rising = score_2024[i] >= score_2023[i] + color = rising ? IMPRINT_INCREASE : IMPRINT_DECREASE + label = rising ? "Increase" : "Decrease" + + lines!(ax, [0, 1], [score_2023[i], score_2024[i]]; + color=color, linewidth=2.8, label=label) + scatter!(ax, [0, 1], [score_2023[i], score_2024[i]]; + color=color, markersize=13, strokewidth=1.5, strokecolor=PAGE_BG) + + text!(ax, -0.05, label_y_left[i]; text="$(products[i]) $(score_2023[i])", + align=(:right, :center), color=INK, fontsize=15) + text!(ax, 1.05, label_y_right[i]; text="$(score_2024[i]) $(products[i])", + align=(:left, :center), color=INK, fontsize=15) +end + +# Survey-year headers atop each vertical axis +text!(ax, 0, ylim_hi - y_pad * 0.5; text="2023 Survey", align=(:center, :bottom), + color=INK_SOFT, fontsize=15, font=:bold) +text!(ax, 1, ylim_hi - y_pad * 0.5; text="2024 Survey", align=(:center, :bottom), + color=INK_SOFT, fontsize=15, font=:bold) + +Legend(fig[1, 2], ax; merge=true, unique=true, framevisible=false, + labelcolor=INK, labelsize=13, patchsize=(22, 3), tellheight=false, valign=:center) +colsize!(fig.layout, 2, Fixed(150)) + +# --- Save -------------------------------------------------------------- +save("plot-$(THEME).png", fig; px_per_unit=2) From 4fceaa6fbea551ae769d36a213247fe343da8765 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 25 Jul 2026 23:56:01 +0000 Subject: [PATCH 2/5] chore(makie): add metadata for slope-basic --- plots/slope-basic/metadata/julia/makie.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 plots/slope-basic/metadata/julia/makie.yaml diff --git a/plots/slope-basic/metadata/julia/makie.yaml b/plots/slope-basic/metadata/julia/makie.yaml new file mode 100644 index 0000000000..92b7da8d81 --- /dev/null +++ b/plots/slope-basic/metadata/julia/makie.yaml @@ -0,0 +1,21 @@ +# Per-library metadata for makie implementation of slope-basic +# Auto-generated by impl-generate.yml + +library: makie +language: julia +specification_id: slope-basic +created: '2026-07-25T23:56:00Z' +updated: '2026-07-25T23:56:00Z' +generated_by: claude-sonnet +workflow_run: 30179763349 +issue: 981 +language_version: 1.11.9 +library_version: 0.21.9 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/slope-basic/julia/makie/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/slope-basic/julia/makie/plot-dark.png +preview_html_light: null +preview_html_dark: null +quality_score: null +review: + strengths: [] + weaknesses: [] From 85364cd9ae45923e45f225e26bacf1c15761ebb5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jul 2026 00:01:56 +0000 Subject: [PATCH 3/5] chore(makie): update quality score 86 and review feedback for slope-basic --- .../implementations/julia/makie.jl | 4 +- plots/slope-basic/metadata/julia/makie.yaml | 234 +++++++++++++++++- 2 files changed, 229 insertions(+), 9 deletions(-) diff --git a/plots/slope-basic/implementations/julia/makie.jl b/plots/slope-basic/implementations/julia/makie.jl index c13aecac4a..86d0f1ba67 100644 --- a/plots/slope-basic/implementations/julia/makie.jl +++ b/plots/slope-basic/implementations/julia/makie.jl @@ -1,7 +1,7 @@ # anyplot.ai # slope-basic: Basic Slope Chart (Slopegraph) -# Library: Makie.jl 0.22 | Julia 1.11 -# Quality: pending | Created: 2026-07-25 +# Library: makie 0.21.9 | Julia 1.11.9 +# Quality: 86/100 | Updated: 2026-07-26 using CairoMakie using Colors diff --git a/plots/slope-basic/metadata/julia/makie.yaml b/plots/slope-basic/metadata/julia/makie.yaml index 92b7da8d81..75aabfdfc1 100644 --- a/plots/slope-basic/metadata/julia/makie.yaml +++ b/plots/slope-basic/metadata/julia/makie.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for makie implementation of slope-basic -# Auto-generated by impl-generate.yml - library: makie language: julia specification_id: slope-basic created: '2026-07-25T23:56:00Z' -updated: '2026-07-25T23:56:00Z' +updated: '2026-07-26T00:01:55Z' generated_by: claude-sonnet workflow_run: 30179763349 issue: 981 @@ -15,7 +12,230 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/slope-bas preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/slope-basic/julia/makie/plot-dark.png preview_html_light: null preview_html_dark: null -quality_score: null +quality_score: 86 review: - strengths: [] - weaknesses: [] + strengths: + - 'Correct slopegraph structure: two vertical time-point axes labeled "2023 Survey"/"2024 + Survey" with endpoint labels on both sides, exactly per spec notes' + - Semantic red/green color-coding for decrease/increase follows the Imprint style + guide's finance semantic-exception rule (profit/up/gain→green, loss/down→red), + and is identical across both themes + - Custom label anti-collision (min_gap nudging loop) keeps all 20 endpoint labels + legible even where raw scores cluster tightly + - Entities sorted by descending 2023 score, giving the chart a clear top-to-bottom + rank ordering that aids scanning + - 'Clean minimalist chrome: spines and default decorations fully hidden, no gridlines, + generous whitespace, subtle bold survey-year headers' + - Theme-adaptive chrome correctly threaded through PAGE_BG/INK/INK_SOFT tokens — + both renders pass the light/dark legibility check + - 'Idiomatic Makie usage: GridLayout-based legend placement (fig[1,2] + colsize!) + with merge=true/unique=true, hidedecorations!/hidespines!, deterministic Random.seed!(42)' + weaknesses: + - No label anywhere on the chart indicates what the numeric values represent (e.g. + "Customer Satisfaction Score (0–100)") — the survey-year headers label the x-axis + but the y-values are unitless raw numbers to the viewer; add a small subtitle + or axis caption near the vertical axes + - In the densest score bands (e.g. Cloud Storage 54.1 vs Payment Gateway 53.8; Video + Conferencing 61.7 vs Customer Portal 61.0), the anti-collision nudge pushes label + text noticeably away from its true marker/line position with no leader stub connecting + them, making it harder to trace which label belongs to which line exactly where + it matters most + - Decrease/Increase is communicated only through red vs green in the legend; while + the line's up/down slope is redundant geometric information, a small directional + glyph (▲/▼) next to each value would make the encoding fully CVD-robust without + relying on the legend at all + - Legend column on the right carries a lot of unused vertical whitespace around + just two entries — tightening the column or nudging the legend toward the chart's + vertical center of mass would improve canvas balance + image_description: |- + Light render (plot-light.png): + Background: Warm off-white, matches #FAF8F1, not pure white. + Chrome: Title "slope-basic · julia · makie · anyplot.ai" is bold, dark ink, centered at top, fully visible with no clipping. "2023 Survey" / "2024 Survey" headers sit atop each vertical reference axis in medium-gray bold text. Ten product names + scores flank both axes in dark ink text. Legend ("Decrease" / "Increase") sits in a dedicated right-hand column, readable dark text on the light background. + Data: Ten diagonal lines connect 2023 to 2024 scores, colored matte red (#AE3030, decrease) or brand green (#009E73, increase), with small circular markers (white/cream stroke) at each endpoint. + Legibility verdict: PASS — all title, header, label, and legend text is clearly readable against the light background; no light-on-light issues. + + Dark render (plot-dark.png): + Background: Warm near-black, matches #1A1A17, not pure black. + Chrome: Same title, headers, and per-entity labels now rendered in light ink (#F0EFE8 title / #B8B7B0 headers), clearly legible against the dark surface. Legend text also flips to light ink. + Data: Same red (#AE3030) and green (#009E73) line/marker colors as the light render — confirmed identical data colors between themes, only chrome (background + text) flipped. + Legibility verdict: PASS — no dark-on-dark failures observed; all text (title, headers, entity labels, legend) reads clearly against the near-black background. Brand green and matte red both remain clearly visible on the dark surface. + criteria_checklist: + visual_quality: + score: 25 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: All font sizes explicitly set (titlesize=20, labelsize=15, legend + 13, headers 15); readable in both themes with no overflow + - id: VQ-02 + name: No Overlap + score: 5 + max: 6 + passed: true + comment: No literal text-on-text overlap, but nudged labels drift noticeably + from their true marker in the densest score clusters with no leader stub + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: Sparse data (10 entities) given prominent markers (markersize=13) + and thick lines (linewidth=2.8) + - id: VQ-04 + name: Color Accessibility + score: 1 + max: 2 + passed: false + comment: Red/green is the only explicit legend-level distinguishing cue, though + slope direction is a redundant geometric signal + - id: VQ-05 + name: Layout & Canvas + score: 3 + max: 4 + passed: true + comment: Good overall balance and use of canvas; legend column carries excess + unused whitespace around two entries + - id: VQ-06 + name: Axis Labels & Title + score: 1 + max: 2 + passed: false + comment: Time points labeled (2023/2024 Survey) but no label/units anywhere + for what the numeric values represent + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: Exact Imprint hexes (#009E73/#AE3030) used under the documented finance + semantic exception; theme-correct chrome in both renders + design_excellence: + score: 14 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + comment: Thoughtful semantic color use and intentional rank-sorted hierarchy, + clearly above library defaults + - id: DE-02 + name: Visual Refinement + score: 5 + max: 6 + comment: Spines/decorations fully hidden, no grid, generous whitespace, refined + marker strokes + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + comment: Color contrast + descending sort create clear visual hierarchy, though + the missing value-axis label costs some immediate clarity + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + comment: Correct slopegraph + - id: SC-02 + name: Required Features + score: 4 + max: 4 + comment: Endpoint labels, direction color-coding, labeled vertical axes, 10 + entities (within 5-15 range) + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + comment: X/Y correctly assigned, all data visible + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + comment: Title format exact; legend labels match the semantic split + data_quality: + score: 14 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 5 + max: 6 + comment: Mix of increases and decreases at varied magnitudes + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + comment: Customer satisfaction survey scores across product lines — real, + neutral, business-plausible + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + comment: Scores in 48-100 range clamped sensibly for a 0-100 satisfaction + scale + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + comment: No functions/classes; linear imports→data→plot→save flow + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + comment: Random.seed!(42) + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + comment: CairoMakie, Colors, Random all used + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + comment: No fake UI; nudge-loop complexity is justified by the label-collision + problem it solves + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + comment: save("plot-$(THEME).png", fig; px_per_unit=2), current API + library_mastery: + score: 8 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 5 + max: 5 + comment: hidedecorations!/hidespines!, vlines!/lines!/scatter!/text!, Legend + with merge/unique — idiomatic high-level Makie API throughout + - id: LM-02 + name: Distinctive Features + score: 3 + max: 5 + comment: GridLayout-based legend column (fig[1,2] + colsize!) is a Makie-distinctive + layout mechanism, though not a rare/showcase feature + verdict: REJECTED +impl_tags: + dependencies: [] + techniques: + - annotations + - custom-legend + patterns: + - data-generation + - iteration-over-groups + dataprep: [] + styling: + - minimal-chrome From 6583741652af1e87477dbc51387612ba910767c6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jul 2026 00:06:46 +0000 Subject: [PATCH 4/5] fix(makie): address review feedback for slope-basic Attempt 1/4 - fixes based on AI review --- .../implementations/julia/makie.jl | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/plots/slope-basic/implementations/julia/makie.jl b/plots/slope-basic/implementations/julia/makie.jl index 86d0f1ba67..c554d3e41a 100644 --- a/plots/slope-basic/implementations/julia/makie.jl +++ b/plots/slope-basic/implementations/julia/makie.jl @@ -88,6 +88,9 @@ ax = Axis( title = title_text, titlesize = 20, titlecolor = INK, + subtitle = "Customer Satisfaction Score (0–100)", + subtitlesize = 14, + subtitlecolor = INK_SOFT, backgroundcolor = PAGE_BG, ) hidedecorations!(ax) @@ -102,15 +105,28 @@ for i in 1:n rising = score_2024[i] >= score_2023[i] color = rising ? IMPRINT_INCREASE : IMPRINT_DECREASE label = rising ? "Increase" : "Decrease" + arrow = rising ? "▲" : "▼" lines!(ax, [0, 1], [score_2023[i], score_2024[i]]; color=color, linewidth=2.8, label=label) scatter!(ax, [0, 1], [score_2023[i], score_2024[i]]; color=color, markersize=13, strokewidth=1.5, strokecolor=PAGE_BG) + # Leader stubs: connect a nudged label back to its true marker position + # whenever the anti-collision loop moved it, so the label-to-line link + # stays traceable even when several labels cluster in a dense band. + if abs(label_y_left[i] - score_2023[i]) > 1e-6 + lines!(ax, [-0.05, 0], [label_y_left[i], score_2023[i]]; + color=INK_SOFT, linewidth=0.75, linestyle=:dot) + end + if abs(label_y_right[i] - score_2024[i]) > 1e-6 + lines!(ax, [1, 1.05], [score_2024[i], label_y_right[i]]; + color=INK_SOFT, linewidth=0.75, linestyle=:dot) + end + text!(ax, -0.05, label_y_left[i]; text="$(products[i]) $(score_2023[i])", align=(:right, :center), color=INK, fontsize=15) - text!(ax, 1.05, label_y_right[i]; text="$(score_2024[i]) $(products[i])", + text!(ax, 1.05, label_y_right[i]; text="$(arrow) $(score_2024[i]) $(products[i])", align=(:left, :center), color=INK, fontsize=15) end @@ -122,7 +138,7 @@ text!(ax, 1, ylim_hi - y_pad * 0.5; text="2024 Survey", align=(:center, :bottom) Legend(fig[1, 2], ax; merge=true, unique=true, framevisible=false, labelcolor=INK, labelsize=13, patchsize=(22, 3), tellheight=false, valign=:center) -colsize!(fig.layout, 2, Fixed(150)) +colsize!(fig.layout, 2, Fixed(105)) # --- Save -------------------------------------------------------------- save("plot-$(THEME).png", fig; px_per_unit=2) From b4ba9e5ab1525c5886bb09ce2fb0ea4772bc72eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 26 Jul 2026 00:10:51 +0000 Subject: [PATCH 5/5] chore(makie): update quality score 92 and review feedback for slope-basic --- .../implementations/julia/makie.jl | 2 +- plots/slope-basic/metadata/julia/makie.yaml | 176 ++++++++++-------- 2 files changed, 101 insertions(+), 77 deletions(-) diff --git a/plots/slope-basic/implementations/julia/makie.jl b/plots/slope-basic/implementations/julia/makie.jl index c554d3e41a..885e37c8f3 100644 --- a/plots/slope-basic/implementations/julia/makie.jl +++ b/plots/slope-basic/implementations/julia/makie.jl @@ -1,7 +1,7 @@ # anyplot.ai # slope-basic: Basic Slope Chart (Slopegraph) # Library: makie 0.21.9 | Julia 1.11.9 -# Quality: 86/100 | Updated: 2026-07-26 +# Quality: 92/100 | Updated: 2026-07-26 using CairoMakie using Colors diff --git a/plots/slope-basic/metadata/julia/makie.yaml b/plots/slope-basic/metadata/julia/makie.yaml index 75aabfdfc1..c6c98e0753 100644 --- a/plots/slope-basic/metadata/julia/makie.yaml +++ b/plots/slope-basic/metadata/julia/makie.yaml @@ -2,7 +2,7 @@ library: makie language: julia specification_id: slope-basic created: '2026-07-25T23:56:00Z' -updated: '2026-07-26T00:01:55Z' +updated: '2026-07-26T00:10:51Z' generated_by: claude-sonnet workflow_run: 30179763349 issue: 981 @@ -12,56 +12,57 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/slope-bas preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/slope-basic/julia/makie/plot-dark.png preview_html_light: null preview_html_dark: null -quality_score: 86 +quality_score: 92 review: strengths: + - 'All four attempt-1 weaknesses are directly and correctly addressed: a subtitle + now labels the value axis ("Customer Satisfaction Score (0–100)"), dotted leader + stubs reconnect nudged labels to their true marker positions in the densest score + clusters, ▲/▼ glyphs make the increase/decrease encoding CVD-safe independent + of color, and the legend column was narrowed (Fixed(150) → Fixed(105)) to cut + unused whitespace' - 'Correct slopegraph structure: two vertical time-point axes labeled "2023 Survey"/"2024 - Survey" with endpoint labels on both sides, exactly per spec notes' + Survey" with endpoint labels on both sides, matching the spec notes exactly' - Semantic red/green color-coding for decrease/increase follows the Imprint style - guide's finance semantic-exception rule (profit/up/gain→green, loss/down→red), - and is identical across both themes - - Custom label anti-collision (min_gap nudging loop) keeps all 20 endpoint labels - legible even where raw scores cluster tightly - - Entities sorted by descending 2023 score, giving the chart a clear top-to-bottom - rank ordering that aids scanning + guide's semantic-exception rule, and the exact hex values are identical across + both themes + - Theme-adaptive chrome correctly threaded through PAGE_BG/INK/INK_SOFT tokens — + both renders pass the light/dark legibility check with no dark-on-dark or light-on-light + failures - 'Clean minimalist chrome: spines and default decorations fully hidden, no gridlines, generous whitespace, subtle bold survey-year headers' - - Theme-adaptive chrome correctly threaded through PAGE_BG/INK/INK_SOFT tokens — - both renders pass the light/dark legibility check - 'Idiomatic Makie usage: GridLayout-based legend placement (fig[1,2] + colsize!) with merge=true/unique=true, hidedecorations!/hidespines!, deterministic Random.seed!(42)' + - Entities sorted by descending 2023 score, giving the chart a clear top-to-bottom + rank ordering that aids scanning weaknesses: - - No label anywhere on the chart indicates what the numeric values represent (e.g. - "Customer Satisfaction Score (0–100)") — the survey-year headers label the x-axis - but the y-values are unitless raw numbers to the viewer; add a small subtitle - or axis caption near the vertical axes - - In the densest score bands (e.g. Cloud Storage 54.1 vs Payment Gateway 53.8; Video - Conferencing 61.7 vs Customer Portal 61.0), the anti-collision nudge pushes label - text noticeably away from its true marker/line position with no leader stub connecting - them, making it harder to trace which label belongs to which line exactly where - it matters most - - Decrease/Increase is communicated only through red vs green in the legend; while - the line's up/down slope is redundant geometric information, a small directional - glyph (▲/▼) next to each value would make the encoding fully CVD-robust without - relying on the legend at all - - Legend column on the right carries a lot of unused vertical whitespace around - just two entries — tightening the column or nudging the legend toward the chart's - vertical center of mass would improve canvas balance + - Distinctive Makie-specific features are still underused — the chart relies on + generic primitives (lines!, scatter!, text!) that read as library-agnostic; leaning + on more Makie-specific machinery (e.g. Observables-driven layout tuning, a custom + recipe, richer Scene/Axis composition) would raise Library Mastery + - In the tightest score band (Video Conferencing 61.7 / Customer Portal 61.0 / Mobile + App 59.3 on the left; the 54.x/52.9 cluster at the bottom), label rows sit close + enough together that legibility could soften further at small preview sizes (~400px) + even though the anti-collision nudge keeps them technically non-overlapping at + full resolution + - Aesthetic sophistication is solid but still fairly close to a standard slopegraph + template — an additional refinement (e.g. subtle marker-size or opacity encoding + for magnitude of change) would push Design Excellence higher image_description: |- Light render (plot-light.png): - Background: Warm off-white, matches #FAF8F1, not pure white. - Chrome: Title "slope-basic · julia · makie · anyplot.ai" is bold, dark ink, centered at top, fully visible with no clipping. "2023 Survey" / "2024 Survey" headers sit atop each vertical reference axis in medium-gray bold text. Ten product names + scores flank both axes in dark ink text. Legend ("Decrease" / "Increase") sits in a dedicated right-hand column, readable dark text on the light background. - Data: Ten diagonal lines connect 2023 to 2024 scores, colored matte red (#AE3030, decrease) or brand green (#009E73, increase), with small circular markers (white/cream stroke) at each endpoint. - Legibility verdict: PASS — all title, header, label, and legend text is clearly readable against the light background; no light-on-light issues. + Background: Warm off-white, matches #FAF8F1, not pure white, not dark. + Chrome: Title "slope-basic · julia · makie · anyplot.ai" is bold, dark ink, centered at top, fully visible with no clipping. A new subtitle "Customer Satisfaction Score (0–100)" sits directly beneath it, correctly labeling what the y-values represent. "2023 Survey" / "2024 Survey" headers sit atop each vertical reference axis in medium-gray bold text. Ten product names + scores flank both axes in dark ink text, and the right-hand labels now carry ▲/▼ direction glyphs before each value. Thin dotted leader stubs connect nudged labels back to their true marker/line position wherever the anti-collision loop moved them. Legend ("Decrease" / "Increase") sits in a narrowed right-hand column, readable dark text on the light background. + Data: Ten diagonal lines connect 2023 to 2024 scores, colored matte red (#AE3030, decrease) or brand green (#009E73, increase), with small circular markers (cream stroke) at each endpoint. + Legibility verdict: PASS — all title, subtitle, header, label, and legend text is clearly readable against the light background; no light-on-light issues. Dark render (plot-dark.png): - Background: Warm near-black, matches #1A1A17, not pure black. - Chrome: Same title, headers, and per-entity labels now rendered in light ink (#F0EFE8 title / #B8B7B0 headers), clearly legible against the dark surface. Legend text also flips to light ink. + Background: Warm near-black, matches #1A1A17, not pure black, not light. + Chrome: Same title, subtitle, headers, and per-entity labels (including the ▲/▼ glyphs and leader stubs) now rendered in light ink (#F0EFE8 title / #B8B7B0 headers and subtitle), clearly legible against the dark surface. Legend text also flips to light ink. Data: Same red (#AE3030) and green (#009E73) line/marker colors as the light render — confirmed identical data colors between themes, only chrome (background + text) flipped. - Legibility verdict: PASS — no dark-on-dark failures observed; all text (title, headers, entity labels, legend) reads clearly against the near-black background. Brand green and matte red both remain clearly visible on the dark surface. + Legibility verdict: PASS — no dark-on-dark failures observed; all text (title, subtitle, headers, entity labels, legend) reads clearly against the near-black background. Brand green and matte red both remain clearly visible on the dark surface. criteria_checklist: visual_quality: - score: 25 + score: 29 max: 30 items: - id: VQ-01 @@ -69,15 +70,17 @@ review: score: 7 max: 8 passed: true - comment: All font sizes explicitly set (titlesize=20, labelsize=15, legend - 13, headers 15); readable in both themes with no overflow + comment: All font sizes explicit (titlesize=20, subtitlesize=14, labelsize=15, + legend 13, headers 15); readable in both themes. Densest score clusters + could soften slightly at small preview sizes. - id: VQ-02 name: No Overlap - score: 5 + score: 6 max: 6 passed: true - comment: No literal text-on-text overlap, but nudged labels drift noticeably - from their true marker in the densest score clusters with no leader stub + comment: New dotted leader stubs eliminate the ambiguity flagged in attempt + 1 — every nudged label is now traceable back to its true marker even in + dense clusters - id: VQ-03 name: Element Visibility score: 6 @@ -87,54 +90,58 @@ review: and thick lines (linewidth=2.8) - id: VQ-04 name: Color Accessibility - score: 1 + score: 2 max: 2 - passed: false - comment: Red/green is the only explicit legend-level distinguishing cue, though - slope direction is a redundant geometric signal + passed: true + comment: New ▲/▼ glyphs make increase/decrease fully CVD-robust independent + of the legend/color, fixing the attempt-1 gap - id: VQ-05 name: Layout & Canvas - score: 3 + score: 4 max: 4 passed: true - comment: Good overall balance and use of canvas; legend column carries excess - unused whitespace around two entries + comment: Legend column narrowed (150px → 105px), canvas gate passed, nothing + cut off - id: VQ-06 name: Axis Labels & Title - score: 1 + score: 2 max: 2 - passed: false - comment: Time points labeled (2023/2024 Survey) but no label/units anywhere - for what the numeric values represent + passed: true + comment: New subtitle explicitly labels the value axis ("Customer Satisfaction + Score (0–100)"), fixing the attempt-1 gap - id: VQ-07 name: Palette Compliance score: 2 max: 2 passed: true - comment: Exact Imprint hexes (#009E73/#AE3030) used under the documented finance - semantic exception; theme-correct chrome in both renders + comment: Exact Imprint hexes (#009E73/#AE3030) under the documented semantic + exception; theme-correct chrome in both renders design_excellence: - score: 14 + score: 16 max: 20 items: - id: DE-01 name: Aesthetic Sophistication - score: 5 + score: 6 max: 8 - comment: Thoughtful semantic color use and intentional rank-sorted hierarchy, - clearly above library defaults + passed: true + comment: Semantic color, rank-sorted hierarchy, leader stubs and direction + glyphs go clearly beyond library defaults, though the overall template stays + close to a standard slopegraph - id: DE-02 name: Visual Refinement score: 5 max: 6 + passed: true comment: Spines/decorations fully hidden, no grid, generous whitespace, refined - marker strokes + marker strokes and subtle dotted leader lines - id: DE-03 name: Data Storytelling - score: 4 + score: 5 max: 6 - comment: Color contrast + descending sort create clear visual hierarchy, though - the missing value-axis label costs some immediate clarity + passed: true + comment: Color contrast, descending sort, and direction glyphs together create + a clear, legible visual hierarchy spec_compliance: score: 15 max: 15 @@ -143,42 +150,49 @@ review: name: Plot Type score: 5 max: 5 + passed: true comment: Correct slopegraph - id: SC-02 name: Required Features score: 4 max: 4 - comment: Endpoint labels, direction color-coding, labeled vertical axes, 10 - entities (within 5-15 range) + passed: true + comment: Endpoint labels, direction color+glyph coding, labeled vertical axes, + 10 entities (within 5-15 range) - id: SC-03 name: Data Mapping score: 3 max: 3 + passed: true comment: X/Y correctly assigned, all data visible - id: SC-04 name: Title & Legend score: 3 max: 3 + passed: true comment: Title format exact; legend labels match the semantic split data_quality: - score: 14 + score: 15 max: 15 items: - id: DQ-01 name: Feature Coverage - score: 5 + score: 6 max: 6 + passed: true comment: Mix of increases and decreases at varied magnitudes - id: DQ-02 name: Realistic Context score: 5 max: 5 + passed: true comment: Customer satisfaction survey scores across product lines — real, neutral, business-plausible - id: DQ-03 name: Appropriate Scale score: 4 max: 4 + passed: true comment: Scores in 48-100 range clamped sensibly for a 0-100 satisfaction scale code_quality: @@ -189,45 +203,54 @@ review: name: KISS Structure score: 3 max: 3 + passed: true comment: No functions/classes; linear imports→data→plot→save flow - id: CQ-02 name: Reproducibility score: 2 max: 2 + passed: true comment: Random.seed!(42) - id: CQ-03 name: Clean Imports score: 2 max: 2 - comment: CairoMakie, Colors, Random all used + passed: true + comment: CairoMakie, Colors, Random all used; no unused imports - id: CQ-04 name: Code Elegance score: 2 max: 2 - comment: No fake UI; nudge-loop complexity is justified by the label-collision - problem it solves + passed: true + comment: No fake functionality; anti-collision loop and leader stubs are proportionate + complexity for the problem - id: CQ-05 name: Output & API score: 1 max: 1 - comment: save("plot-$(THEME).png", fig; px_per_unit=2), current API + passed: true + comment: save("plot-$(THEME).png", fig; px_per_unit=2) matches the required + pattern library_mastery: - score: 8 + score: 7 max: 10 items: - id: LM-01 name: Idiomatic Usage - score: 5 + score: 4 max: 5 - comment: hidedecorations!/hidespines!, vlines!/lines!/scatter!/text!, Legend - with merge/unique — idiomatic high-level Makie API throughout + passed: true + comment: GridLayout-based legend (fig[1,2] + colsize!), hidedecorations!/hidespines!, + vlines! for reference axes - id: LM-02 name: Distinctive Features score: 3 max: 5 - comment: GridLayout-based legend column (fig[1,2] + colsize!) is a Makie-distinctive - layout mechanism, though not a rare/showcase feature - verdict: REJECTED + passed: true + comment: Custom label anti-collision + leader-stub system is a genuine Makie + composition, but core marks (lines!, scatter!, text!) remain generic rather + than showcasing library-unique features + verdict: APPROVED impl_tags: dependencies: [] techniques: @@ -239,3 +262,4 @@ impl_tags: dataprep: [] styling: - minimal-chrome + - edge-highlighting