{"spec_id":"timeline-basic","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' timeline-basic: Event Timeline\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 89/100 | Created: 2026-09-09\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(ragg)\n\nset.seed(42)\n\n# --- Theme tokens -------------------------------------------------------\nTHEME       <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG     <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\n\nIMPRINT_PALETTE <- c(\n  \"#009E73\", # 1 - Team (brand green)\n  \"#C475FD\", # 2 - Product (lavender)\n  \"#4467A3\", # 3 - Funding (blue)\n  \"#BD8233\"  # 4 - Expansion (ochre)\n)\n\n# --- Data: company milestones since founding -----------------------------\nmilestones <- tibble::tibble(\n  date = as.Date(c(\n    \"2018-03-01\", \"2018-09-15\", \"2019-05-01\", \"2019-11-20\",\n    \"2020-04-01\", \"2020-10-05\", \"2021-06-15\", \"2021-12-01\",\n    \"2022-03-10\", \"2022-08-20\", \"2023-02-14\", \"2023-09-01\",\n    \"2024-05-15\"\n  )),\n  event = c(\n    \"Company Founded\", \"Seed Funding\", \"MVP Launch\", \"Series A\",\n    \"10th Employee\", \"Mobile App Launch\", \"European Expansion\", \"Series B\",\n    \"100th Employee\", \"Enterprise Tier Launch\", \"Asia-Pacific Expansion\",\n    \"Series C\", \"IPO Announcement\"\n  ),\n  category = factor(\n    c(\n      \"Team\", \"Funding\", \"Product\", \"Funding\",\n      \"Team\", \"Product\", \"Expansion\", \"Funding\",\n      \"Team\", \"Product\", \"Expansion\", \"Funding\", \"Funding\"\n    ),\n    levels = c(\"Team\", \"Product\", \"Funding\", \"Expansion\")\n  )\n) %>%\n  arrange(date) %>%\n  mutate(\n    above = row_number() %% 2 == 1,\n    label = paste0(event, \"\\n\", format(date, \"%b %Y\"))\n  ) %>%\n  group_by(above) %>%\n  mutate(tier = (row_number() - 1) %% 3 + 1) %>%\n  ungroup() %>%\n  mutate(label_y = (0.9 + (tier - 1) * 0.7) * ifelse(above, 1, -1))\n\n# --- Plot -----------------------------------------------------------------\np <- ggplot(milestones) +\n  geom_hline(yintercept = 0, color = INK_SOFT, linewidth = 0.4) +\n  geom_segment(\n    aes(x = date, xend = date, y = 0, yend = label_y, color = category),\n    linewidth = 0.7\n  ) +\n  geom_point(\n    aes(x = date, y = 0, color = category),\n    size = 3.2\n  ) +\n  geom_text(\n    aes(\n      x = date, y = label_y, label = label,\n      vjust = ifelse(above, -0.15, 1.15)\n    ),\n    color = INK, size = 3, lineheight = 0.95, fontface = \"plain\"\n  ) +\n  scale_color_manual(values = IMPRINT_PALETTE, name = \"Category\") +\n  scale_x_date(date_breaks = \"1 year\", date_labels = \"%Y\") +\n  scale_y_continuous(limits = c(-2.7, 2.7)) +\n  labs(\n    title = \"Company Milestones · timeline-basic · r · ggplot2 · anyplot.ai\",\n    x = \"Year\",\n    y = NULL\n  ) +\n  theme_minimal(base_size = 8) +\n  theme(\n    plot.background     = element_rect(fill = PAGE_BG, color = PAGE_BG),\n    panel.background    = element_rect(fill = PAGE_BG, color = NA),\n    panel.grid.major.x  = element_line(color = INK, linewidth = 0.2),\n    panel.grid.minor.x  = element_blank(),\n    panel.grid.major.y  = element_blank(),\n    panel.grid.minor.y  = element_blank(),\n    axis.title.x        = element_text(color = INK, size = 10),\n    axis.text.x         = element_text(color = INK_SOFT, size = 8),\n    axis.title.y        = element_blank(),\n    axis.text.y         = element_blank(),\n    axis.ticks          = element_blank(),\n    plot.title          = element_text(color = INK, size = 12),\n    legend.position     = \"bottom\",\n    legend.background   = element_rect(fill = PAGE_BG, color = NA),\n    legend.text         = element_text(color = INK_SOFT, size = 8),\n    legend.title        = element_text(color = INK, size = 10),\n    plot.margin         = margin(t = 12, r = 20, b = 8, l = 20)\n  ) +\n  coord_cartesian(clip = \"off\")\n\n# --- Save -------------------------------------------------------------------\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 8,\n  height   = 4.5,\n  units    = \"in\",\n  dpi      = 400\n)\n"}