{"spec_id":"gauge-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# gauge-basic: Basic Gauge Chart\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 90/100 | Created: 2026-06-30\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\"\n\n# Imprint palette colors for zone semantics\nconst ZONE_RED   = colorant\"#AE3030\"   # matte red   — poor\nconst ZONE_AMBER = colorant\"#DDCC77\"   # amber       — acceptable\nconst ZONE_GREEN = colorant\"#009E73\"   # brand green — good\n\n# Gauge data — Customer Satisfaction Score (CSAT)\ncsat_score = 78.0\ngauge_min  = 0.0\ngauge_max  = 100.0\nthresh_lo  = 40.0   # poor / acceptable boundary\nthresh_hi  = 70.0   # acceptable / good boundary\n\n# Angle mapping: value → arc angle (π at left/min, 0 at right/max)\nθ_min = π\nθ_lo  = π * (1.0 - (thresh_lo - gauge_min) / (gauge_max - gauge_min))\nθ_hi  = π * (1.0 - (thresh_hi - gauge_min) / (gauge_max - gauge_min))\nθ_max = 0.0\nθ_val = π * (1.0 - (csat_score - gauge_min) / (gauge_max - gauge_min))\n\n# Arc geometry\nr_in  = 0.58\nr_out = 1.00\nn_pts = 150\n\n# Red zone sector: π down to θ_lo\nθ_red = range(θ_min, θ_lo, n_pts)\nred_sector = vcat(\n    [Point2f(r_out * cos(θ), r_out * sin(θ)) for θ in θ_red],\n    [Point2f(r_in  * cos(θ), r_in  * sin(θ)) for θ in reverse(θ_red)],\n)\n\n# Amber zone sector: θ_lo down to θ_hi\nθ_amb = range(θ_lo, θ_hi, n_pts)\namb_sector = vcat(\n    [Point2f(r_out * cos(θ), r_out * sin(θ)) for θ in θ_amb],\n    [Point2f(r_in  * cos(θ), r_in  * sin(θ)) for θ in reverse(θ_amb)],\n)\n\n# Green zone sector: θ_hi down to 0\nθ_grn = range(θ_hi, θ_max, n_pts)\ngrn_sector = vcat(\n    [Point2f(r_out * cos(θ), r_out * sin(θ)) for θ in θ_grn],\n    [Point2f(r_in  * cos(θ), r_in  * sin(θ)) for θ in reverse(θ_grn)],\n)\n\n# Figure — square canvas\nfig = Figure(\n    size            = (1200, 1200),\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    aspect             = DataAspect(),\n    backgroundcolor    = PAGE_BG,\n    title              = \"gauge-basic · julia · makie · anyplot.ai\",\n    titlesize          = 22,\n    titlecolor         = INK_SOFT,\n    titlegap           = 12,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinevisible   = false,\n    bottomspinevisible = false,\n    xgridvisible       = false,\n    ygridvisible       = false,\n    xticksvisible      = false,\n    yticksvisible      = false,\n    xticklabelsvisible = false,\n    yticklabelsvisible = false,\n)\n\n# Draw three color zones\npoly!(ax, red_sector; color = ZONE_RED,   strokewidth = 0)\npoly!(ax, amb_sector; color = ZONE_AMBER, strokewidth = 0)\npoly!(ax, grn_sector; color = ZONE_GREEN, strokewidth = 0)\n\n# Scale ticks and value labels outside the arc\nfor tv in [0, 20, 40, 60, 80, 100]\n    θt = π * (1.0 - tv / 100.0)\n    lines!(ax,\n        [( r_out + 0.04) * cos(θt), (r_out + 0.11) * cos(θt)],\n        [( r_out + 0.04) * sin(θt), (r_out + 0.11) * sin(θt)];\n        color = INK_SOFT, linewidth = 2,\n    )\n    text!(ax,\n        (r_out + 0.24) * cos(θt),\n        (r_out + 0.24) * sin(θt);\n        text = string(tv),\n        fontsize = 18,\n        align = (:center, :center),\n        color = INK_SOFT,\n    )\nend\n\n# Needle pointing to current value\nr_needle = 0.86\nlines!(ax,\n    [0.0, r_needle * cos(θ_val)],\n    [0.0, r_needle * sin(θ_val)];\n    color = INK, linewidth = 5,\n)\n\n# Center pivot dot\nscatter!(ax, [0.0], [0.0]; color = INK, markersize = 24, strokewidth = 0)\n\n# Value label — prominent display below needle pivot\ntext!(ax, 0.0, -0.18;\n    text = \"$(round(Int, csat_score))%\",\n    fontsize = 100,\n    align = (:center, :center),\n    color = INK,\n)\n\n# Metric name\ntext!(ax, 0.0, -0.52;\n    text = \"Customer Satisfaction Score\",\n    fontsize = 26,\n    align = (:center, :center),\n    color = INK_SOFT,\n)\n\n# Zone legend\nLegend(\n    fig[2, 1],\n    [PolyElement(color = ZONE_RED),\n     PolyElement(color = ZONE_AMBER),\n     PolyElement(color = ZONE_GREEN)],\n    [\"Poor (0–40)\", \"Acceptable (40–70)\", \"Good (70–100)\"];\n    orientation      = :horizontal,\n    framevisible     = false,\n    labelcolor       = INK_SOFT,\n    labelsize        = 20,\n    patchsize        = (30, 18),\n    padding          = (8, 8, 8, 8),\n    backgroundcolor  = PAGE_BG,\n    tellwidth        = false,\n)\n\nrowsize!(fig.layout, 2, Fixed(60))\nlimits!(ax, -1.52, 1.52, -0.78, 1.38)\n\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}