{"spec_id":"network-hierarchical","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' network-hierarchical: Hierarchical Network Graph with Tree Layout\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 81/100 | Created: 2026-05-17\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(tidyr)\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\"\nIMPRINT   <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\",\n                 \"#AE3030\", \"#2ABCCD\", \"#954477\")\n\n# --- Data: Organization hierarchy -------------------------------------------\n# Define nodes with their level (depth in tree)\nnodes <- data.frame(\n  id = c(\"ceo\", \"vp_eng\", \"vp_sales\", \"vp_fin\",\n         \"be_lead\", \"fe_lead\", \"eng_mgr\",\n         \"sales1\", \"sales2\",\n         \"fin_mgr\",\n         \"dev1\", \"dev2\", \"dev3\",\n         \"eng1\", \"eng2\",\n         \"rep1\", \"rep2\", \"rep3\"),\n  label = c(\"CEO\", \"VP\\nEngineering\", \"VP\\nSales\", \"VP\\nFinance\",\n            \"Backend\\nLead\", \"Frontend\\nLead\", \"Eng\\nManager\",\n            \"Sales\\nManager\", \"Sales\\nManager\",\n            \"Finance\\nManager\",\n            \"Developer\", \"Developer\", \"Developer\",\n            \"Engineer\", \"Engineer\",\n            \"Sales\\nRep\", \"Sales\\nRep\", \"Sales\\nRep\"),\n  level = c(0, 1, 1, 1,\n            2, 2, 2,\n            2, 2,\n            2,\n            3, 3, 3,\n            3, 3,\n            3, 3, 3)\n)\n\n# Define edges (parent -> child relationships)\nedges <- data.frame(\n  from_id = c(\"ceo\", \"ceo\", \"ceo\",\n              \"vp_eng\", \"vp_eng\", \"vp_eng\",\n              \"vp_sales\", \"vp_sales\",\n              \"vp_fin\",\n              \"be_lead\", \"be_lead\",\n              \"fe_lead\",\n              \"eng_mgr\",\n              \"sales1\", \"sales1\", \"sales2\", \"sales2\"),\n  to_id = c(\"vp_eng\", \"vp_sales\", \"vp_fin\",\n            \"be_lead\", \"fe_lead\", \"eng_mgr\",\n            \"sales1\", \"sales2\",\n            \"fin_mgr\",\n            \"dev1\", \"dev2\",\n            \"dev3\",\n            \"eng1\",\n            \"rep1\", \"rep2\", \"rep3\", \"rep2\")\n)\n\n# Calculate horizontal positions for each level\nlevel_counts <- nodes %>%\n  group_by(level) %>%\n  mutate(\n    pos_in_level = row_number(),\n    n_at_level = n(),\n    x = pos_in_level - (n_at_level + 1) / 2\n  ) %>%\n  ungroup() %>%\n  select(id, x)\n\n# Add coordinates to nodes\nnodes <- nodes %>%\n  left_join(level_counts, by = \"id\") %>%\n  mutate(y = -level * 2.2)\n\n# Merge coordinates for edges\nedges <- edges %>%\n  left_join(nodes %>% select(id, x, y), by = c(\"from_id\" = \"id\")) %>%\n  rename(x_from = x, y_from = y) %>%\n  left_join(nodes %>% select(id, x, y), by = c(\"to_id\" = \"id\")) %>%\n  rename(x_to = x, y_to = y)\n\n# --- Plot -------------------------------------------------------------------\np <- ggplot() +\n  # Draw edges (parent to child)\n  geom_segment(\n    data = edges,\n    aes(x = x_from, y = y_from, xend = x_to, yend = y_to),\n    color = INK_SOFT, linewidth = 0.75, alpha = 0.6\n  ) +\n  # Draw nodes\n  geom_point(\n    data = nodes,\n    aes(x = x, y = y),\n    color = IMPRINT[1], size = 12, alpha = 0.9\n  ) +\n  # Add node labels\n  geom_text(\n    data = nodes,\n    aes(x = x, y = y, label = label),\n    size = 3.2, color = INK, vjust = 0.5, hjust = 0.5,\n    lineheight = 0.9, fontface = \"plain\"\n  ) +\n  labs(\n    title = \"network-hierarchical · ggplot2 · anyplot.ai\",\n    x = \"\", y = \"\"\n  ) +\n  theme_minimal(base_size = 14) +\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 = element_blank(),\n    axis.text = element_blank(),\n    axis.title = element_blank(),\n    axis.ticks = element_blank(),\n    plot.title = element_text(\n      color = INK, size = 24, hjust = 0.5,\n      margin = margin(b = 25, t = 15)\n    ),\n    plot.margin = margin(30, 40, 30, 40, \"pt\")\n  ) +\n  coord_cartesian(expand = FALSE)\n\n# --- Save -------------------------------------------------------------------\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot = p,\n  device = ragg::agg_png,\n  width = 16,\n  height = 9,\n  units = \"in\",\n  dpi = 300\n)\n"}