{"spec_id":"bullet-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# bullet-basic: Basic Bullet Chart\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 88/100 | Created: 2026-05-29\n\nusing CairoMakie\nusing Colors\n\n# --- Theme tokens -----------------------------------------------------------\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\"\nconst BRAND       = colorant\"#009E73\"  # Imprint palette position 1\n\n# Grayscale background bands (theme-adaptive; spec requires grayscale shading)\nconst BAND_POOR = THEME == \"light\" ? RGBAf(0.67, 0.66, 0.64, 1.0) : RGBAf(0.22, 0.22, 0.21, 1.0)\nconst BAND_SAT  = THEME == \"light\" ? RGBAf(0.78, 0.77, 0.75, 1.0) : RGBAf(0.30, 0.30, 0.29, 1.0)\nconst BAND_GOOD = THEME == \"light\" ? RGBAf(0.88, 0.87, 0.85, 1.0) : RGBAf(0.38, 0.38, 0.37, 1.0)\nconst GRID_CLR  = THEME == \"light\" ?\n    RGBAf(26 / 255, 26 / 255, 23 / 255, 0.12) :\n    RGBAf(240 / 255, 239 / 255, 232 / 255, 0.12)\n\n# --- Data -------------------------------------------------------------------\nlabels  = [\"Q1 Revenue\", \"Customer Satisfaction\", \"Project Completion\", \"Code Quality\", \"Cost Efficiency\"]\nactuals = [82, 78, 68, 91, 38]  # Cost Efficiency at 38 exercises the poor zone (<50)\ntargets = [90, 85, 75, 88, 55]\nn = length(labels)\n\n# --- Plot -------------------------------------------------------------------\ntitle_str  = \"Sales KPI Dashboard · bullet-basic · julia · makie · anyplot.ai\"\ntitle_size = length(title_str) > 67 ? round(Int, 20 * 67 / length(title_str)) : 20\n\nfig = Figure(size = (1600, 900), fontsize = 14, backgroundcolor = PAGE_BG)\n\nax = Axis(\n    fig[1, 1];\n    title             = title_str,\n    titlesize         = title_size,\n    titlecolor        = INK,\n    xlabel            = \"Score (%)\",\n    xlabelsize        = 14,\n    xlabelcolor       = INK,\n    xticklabelsize    = 12,\n    xticklabelcolor   = INK_SOFT,\n    xtickcolor        = INK_SOFT,\n    yticklabelsize    = 12,\n    yticklabelcolor   = INK_SOFT,\n    yticksvisible     = false,\n    backgroundcolor   = PAGE_BG,\n    topspinevisible   = false,\n    rightspinevisible = false,\n    leftspinevisible  = false,\n    bottomspinecolor  = INK_SOFT,\n    xgridcolor        = GRID_CLR,\n    ygridvisible      = false,\n    xminorgridvisible = false,\n    yminorgridvisible = false,\n)\n\nband_h = 0.60\nbar_h  = 0.28\n\nfor i in 1:n\n    y      = Float64(i)\n    actual = Float64(actuals[i])\n    target = Float64(targets[i])\n\n    poly!(ax, Rect2f(0.0,  y - band_h / 2, 50.0, band_h); color = BAND_POOR, strokewidth = 0)\n    poly!(ax, Rect2f(50.0, y - band_h / 2, 25.0, band_h); color = BAND_SAT,  strokewidth = 0)\n    poly!(ax, Rect2f(75.0, y - band_h / 2, 25.0, band_h); color = BAND_GOOD, strokewidth = 0)\n\n    poly!(ax, Rect2f(0.0, y - bar_h / 2, actual, bar_h); color = BRAND, strokewidth = 0)\n\n    lines!(ax, [target, target], [y - band_h / 2 - 0.05, y + band_h / 2 + 0.05];\n           color = INK, linewidth = 4.0)\n\n    exceeds = actuals[i] > targets[i]\n    text!(ax, actual + 1.5, y;\n          text    = \"$(actuals[i])%\",\n          color   = exceeds ? BRAND : INK_SOFT,\n          fontsize = exceeds ? 13 : 11,\n          align   = (:left, :center))\nend\n\nax.yticks    = (Float64.(1:n), labels)\nax.xticks    = [0, 25, 50, 75, 100]\nax.yreversed = true\nxlims!(ax, -2.0, 112.0)\nylims!(ax, 0.3, Float64(n) + 0.7)\n\nLegend(\n    fig[1, 2],\n    [PolyElement(color = BAND_GOOD, strokewidth = 0),\n     PolyElement(color = BAND_SAT,  strokewidth = 0),\n     PolyElement(color = BAND_POOR, strokewidth = 0),\n     PolyElement(color = BRAND,     strokewidth = 0),\n     LineElement(color = INK, linewidth = 4.0)],\n    [\"Good (≥75%)\", \"Satisfactory (50–75%)\", \"Poor (<50%)\", \"Actual\", \"Target\"];\n    backgroundcolor = ELEVATED_BG,\n    framevisible    = false,\n    labelcolor      = INK_SOFT,\n    labelsize       = 11,\n    padding         = (8, 8, 8, 8),\n)\n\ncolsize!(fig.layout, 2, Relative(0.20))\n\n# --- Save -------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}