{"spec_id":"dumbbell-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# dumbbell-basic: Basic Dumbbell Chart\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 88/100 | Created: 2026-06-30\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\nconst THEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nconst INK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst INK_MUTED   = THEME == \"light\" ? colorant\"#6B6A63\" : colorant\"#A8A79F\"\n\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\",  # 1 — brand green (first series)\n    colorant\"#C475FD\",  # 2 — lavender\n    colorant\"#4467A3\",  # 3 — blue\n    colorant\"#BD8233\",  # 4 — ochre\n    colorant\"#AE3030\",  # 5 — matte red\n    colorant\"#2ABCCD\",  # 6 — cyan\n    colorant\"#954477\",  # 7 — rose\n    colorant\"#99B314\",  # 8 — lime\n]\n\n# Data: Department satisfaction scores (scale 1–10) before and after a wellness program\ndepartments_raw = [\"Engineering\", \"Marketing\", \"Finance\", \"Operations\", \"Sales\",\n                   \"HR\", \"Legal\", \"Product\", \"Customer Success\", \"R&D\"]\nbefore_raw = [5.8, 6.2, 5.1, 6.5, 7.2, 6.8, 5.5, 6.0, 7.0, 5.3]\nafter_raw  = [7.9, 7.8, 7.2, 8.1, 8.5, 8.2, 7.4, 7.8, 8.8, 7.1]\n\n# Sort ascending by improvement — largest gain lands at top (y = n)\norder         = sortperm(after_raw .- before_raw)\ndepartments   = departments_raw[order]\nbefore_scores = before_raw[order]\nafter_scores  = after_raw[order]\nimprovements  = after_scores .- before_scores\n\nn     = length(departments)\ny_pos = Float64.(1:n)\n\n# Segment endpoints: pairs [before, after] per category for linesegments!\nseg_x = reduce(vcat, [[before_scores[i], after_scores[i]] for i in 1:n])\nseg_y = reduce(vcat, [[y_pos[i],         y_pos[i]]        for i in 1:n])\n\ntitle_str = \"Employee Satisfaction · dumbbell-basic · julia · makie · anyplot.ai\"\n\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = title_str,\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Satisfaction Score (1–10)\",\n    xlabelcolor        = INK,\n    xlabelsize         = 14,\n    ylabel             = \"Department\",\n    ylabelcolor        = INK,\n    ylabelsize         = 14,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    ytickwidth         = 0,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    yticks             = (y_pos, departments),\n    xgridvisible       = true,\n    ygridvisible       = false,\n    xgridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.12),\n    xminorgridvisible  = false,\n    yminorgridvisible  = false,\n)\n\n# Connecting lines (subtle — should not overpower the dots)\nlinesegments!(ax, seg_x, seg_y; color = INK_MUTED, linewidth = 2.0)\n\n# Dots: pre-program (first series, brand green) and post-program (lavender)\nsc1 = scatter!(ax, before_scores, y_pos;\n    color       = IMPRINT_PALETTE[1],\n    markersize  = 18,\n    strokewidth = 0,\n    label       = \"Pre-Program\",\n)\nsc2 = scatter!(ax, after_scores, y_pos;\n    color       = IMPRINT_PALETTE[2],\n    markersize  = 18,\n    strokewidth = 0,\n    label       = \"Post-Program\",\n)\n\n# Gain delta labels centred above each segment — standout gains (≥ 2.0 pts) are darker/larger\nfor i in 1:n\n    mid_x       = (before_scores[i] + after_scores[i]) / 2\n    delta       = round(improvements[i]; digits = 1)\n    is_standout = improvements[i] >= 2.0\n    text!(ax, mid_x, y_pos[i] + 0.40;\n        text     = \"+$(delta)\",\n        color    = is_standout ? INK_SOFT : INK_MUTED,\n        fontsize = is_standout ? 11 : 9,\n        align    = (:center, :bottom),\n    )\nend\n\naxislegend(ax;\n    position        = :rt,\n    backgroundcolor = ELEVATED_BG,\n    framecolor      = INK_SOFT,\n    labelcolor      = INK_SOFT,\n    labelsize       = 12,\n    framewidth      = 1,\n)\n\nxlims!(ax, 4.2, 10.0)\nylims!(ax, 0.5, Float64(n) + 0.8)\n\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}