{"spec_id":"gauge-activity-rings","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' gauge-activity-rings: Activity Rings Progress Chart\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 88/100 | Created: 2026-06-14\n\nlibrary(ggplot2)\nlibrary(ragg)\n\n# Theme tokens\nTHEME       <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG     <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nELEVATED_BG <- if (THEME == \"light\") \"#FFFDF6\" else \"#242420\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\nINK_MUTED   <- if (THEME == \"light\") \"#6B6A63\" else \"#A8A79F\"\n\n# Imprint palette — first 3 positions for 3 rings\nIMPRINT_PALETTE <- c(\"#009E73\", \"#C475FD\", \"#4467A3\")\n\n# Data — daily fitness tracker goals\nrings <- data.frame(\n  metric = c(\"Move\", \"Exercise\", \"Stand\"),\n  value  = c(420, 25, 9),\n  goal   = c(600, 30, 12),\n  unit   = c(\"kcal\", \"min\", \"hr\"),\n  radius = c(2.8, 2.0, 1.2),\n  color  = IMPRINT_PALETTE,\n  stringsAsFactors = FALSE\n)\nrings$fraction <- pmin(rings$value / rings$goal, 1.0)\n\n# Arc path helpers — clockwise from top (π/2)\nn_pts <- 360\n\nmake_track <- function(r) {\n  a <- seq(pi / 2, pi / 2 - 2 * pi, length.out = n_pts + 1)\n  data.frame(x = r * cos(a), y = r * sin(a))\n}\n\nmake_arc <- function(r, frac) {\n  n <- max(3, round(n_pts * frac) + 1)\n  a <- seq(pi / 2, pi / 2 - frac * 2 * pi, length.out = n)\n  data.frame(x = r * cos(a), y = r * sin(a))\n}\n\n# Build track (full-circle) and arc data frames\ntrack_df <- do.call(rbind, lapply(seq_len(nrow(rings)), function(i) {\n  d       <- make_track(rings$radius[i])\n  d$group <- rings$metric[i]\n  d$color <- rings$color[i]\n  d\n}))\n\narc_df <- do.call(rbind, lapply(seq_len(nrow(rings)), function(i) {\n  d       <- make_arc(rings$radius[i], rings$fraction[i])\n  d$group <- rings$metric[i]\n  d$color <- rings$color[i]\n  d\n}))\n\n# Label block — right side of rings, one group per metric\nlabel_df <- data.frame(\n  lx    = 3.35,\n  ly    = c(1.5, 0.0, -1.5),\n  label = paste0(\n    rings$metric, \"\\n\",\n    rings$value, \"/\", rings$goal, \" \", rings$unit, \"\\n\",\n    round(rings$fraction * 100), \"%\"\n  ),\n  color = rings$color,\n  stringsAsFactors = FALSE\n)\n\n# Center annotation — average completion\navg_pct <- round(mean(rings$fraction) * 100)\n\n# Title (47 chars — no scaling needed)\ntitle_str <- \"gauge-activity-rings · r · ggplot2 · anyplot.ai\"\n\np <- ggplot() +\n  # Faint background tracks (full-circle behind each arc)\n  geom_path(\n    data     = track_df,\n    aes(x = x, y = y, group = group, color = color),\n    linewidth = 9, alpha = 0.15, lineend = \"round\"\n  ) +\n  # Progress arcs\n  geom_path(\n    data     = arc_df,\n    aes(x = x, y = y, group = group, color = color),\n    linewidth = 9, lineend = \"round\"\n  ) +\n  scale_color_identity() +\n  # Right-side metric labels (3 rows each)\n  geom_text(\n    data = label_df,\n    aes(x = lx, y = ly, label = label, color = color),\n    hjust = 0, vjust = 0.5, size = 4.2,\n    lineheight = 1.35, fontface = \"bold\"\n  ) +\n  # Center: average percentage\n  annotate(\n    \"text\", x = 0, y = 0.28,\n    label = paste0(avg_pct, \"%\"),\n    color = INK, size = 7.5, fontface = \"bold\", hjust = 0.5, vjust = 0.5\n  ) +\n  annotate(\n    \"text\", x = 0, y = -0.42,\n    label = \"avg\",\n    color = INK_MUTED, size = 4.5, hjust = 0.5, vjust = 0.5\n  ) +\n  coord_fixed(\n    xlim = c(-3.5, 5.6),\n    ylim = c(-3.5, 3.5)\n  ) +\n  labs(title = title_str) +\n  theme_void() +\n  theme(\n    plot.background  = element_rect(fill = PAGE_BG, color = PAGE_BG),\n    panel.background = element_rect(fill = PAGE_BG, color = NA),\n    plot.title       = element_text(\n      color  = INK, size = 12, hjust = 0.5,\n      margin = margin(t = 18, b = 10)\n    ),\n    plot.margin = margin(20, 20, 20, 20)\n  )\n\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 6,\n  height   = 6,\n  units    = \"in\",\n  dpi      = 400\n)\n"}