Connected Scatterplot

library(ggplot2)
library(ggrepel)

data <- data.frame(
  time  = 2000:2020,
  value = cumsum(rnorm(21, 0.5, 1))   # nilai acak kumulatif
)

data <- data[order(data$time), ]

ggplot(data, aes(x = time, y = value)) +
  geom_point(color = "blue", size = 3) +                 # Titik
  geom_line(color = "darkorange", size = 1) +            # Garis penghubung
  geom_text_repel(aes(label = round(value, 1)), size = 3) + # Label angka
  labs(
    title = "Connected Scatterplot",
    x = "Tahun",
    y = "Nilai"
  ) +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Network graph

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ lubridate 1.9.4     ✔ tibble    3.3.0
## ✔ purrr     1.1.0     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(igraph)
## 
## Attaching package: 'igraph'
## 
## The following objects are masked from 'package:lubridate':
## 
##     %--%, union
## 
## The following objects are masked from 'package:dplyr':
## 
##     as_data_frame, groups, union
## 
## The following objects are masked from 'package:purrr':
## 
##     compose, simplify
## 
## The following object is masked from 'package:tidyr':
## 
##     crossing
## 
## The following object is masked from 'package:tibble':
## 
##     as_data_frame
## 
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## 
## The following object is masked from 'package:base':
## 
##     union
library(ggraph)
library(tidygraph)
## 
## Attaching package: 'tidygraph'
## 
## The following object is masked from 'package:igraph':
## 
##     groups
## 
## The following object is masked from 'package:stats':
## 
##     filter
library(visNetwork)

set.seed(123)

nodes <- tibble(id = 1:15,
                label = paste0("N", id),
                group_hint = sample(letters[1:3], 15, replace = TRUE))

edges <- tibble(
  from = sample(nodes$id, 30, replace = TRUE),
  to   = sample(nodes$id, 30, replace = TRUE),
  weight = round(runif(30, 0.2, 1.0), 2)
) %>%
  filter(from != to) %>%                        # hindari self-loop
  distinct(from, to, .keep_all = TRUE)          # hindari duplikat

g <- graph_from_data_frame(edges, directed = FALSE, vertices = nodes)

# Centrality & komunitas
deg  <- degree(g, mode = "all")
btw  <- betweenness(g, directed = FALSE, normalized = TRUE)
cls  <- cluster_louvain(g)                      # deteksi komunitas Louvain
comm <- membership(cls)

# Gabungkan metrik ke nodes
nodes_metrics <- tibble(
  id = as.integer(V(g)$name),
  label = V(g)$label,
  degree = as.numeric(deg),
  betweenness = as.numeric(btw),
  community = as.factor(comm)
)

# Skala ukuran node dari degree
nodes_metrics <- nodes_metrics %>%
  mutate(size = scales::rescale(degree, to = c(4, 18)))

# Gabungkan bobot edge untuk ketebalan
edges_plot <- as_tibble(get.data.frame(g)) %>%
  rename(from = from, to = to) %>%
  mutate(width = scales::rescale(weight, to = c(0.3, 2.5)))
## Warning: `get.data.frame()` was deprecated in igraph 2.0.0.
## ℹ Please use `as_data_frame()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Konversi ke tidygraph untuk ggraph
tg <- tbl_graph(nodes = nodes_metrics, edges = edges_plot, directed = FALSE)

p <- ggraph(tg, layout = "fr") +
  geom_edge_link(aes(width = width), alpha = 0.4, colour = "grey40") +
  geom_node_point(aes(size = size, color = community), alpha = 0.9) +
  geom_node_text(aes(label = label), repel = TRUE, size = 3) +
  scale_edge_width(range = c(0.2, 2.5), guide = "none") +
  scale_size_identity() +
  labs(title = "Network Graph (Louvain Communities & Degree Size)",
       subtitle = "Ukuran node ~ degree | Warna ~ komunitas | Ketebalan edge ~ bobot",
       x = NULL, y = NULL) +
  theme_graph(base_family = "") +
  theme(legend.position = "right")

print(p)

# Siapkan data sesuai format visNetwork
vn_nodes <- nodes_metrics %>%
  transmute(id = id,
            label = label,
            group = community,
            value = degree,              # kontrol ukuran relatif
            title = paste0(
              "<b>", label, "</b>",
              "<br>Degree: ", degree,
              "<br>Betweenness: ", round(betweenness, 3),
              "<br>Community: ", community
            ))

vn_edges <- edges_plot %>%
  transmute(from = as.integer(from),
            to   = as.integer(to),
            value = weight,
            title = paste0("Weight: ", weight))

vn <- visNetwork(vn_nodes, vn_edges, width = "100%", height = "620px") %>%
  visIgraphLayout(layout = "layout_with_fr") %>%      # layout gaya igraph
  visEdges(smooth = FALSE, color = list(opacity = 0.5)) %>%
  visLegend(useGroups = TRUE, position = "right") %>%
  visOptions(highlightNearest = list(enabled = TRUE, degree = 1),
             nodesIdSelection = TRUE) %>%
  visInteraction(hover = TRUE, dragNodes = TRUE, zoomView = TRUE) %>%
  visPhysics(stabilization = TRUE)

vn

Radar/Spider chart

library(fmsb)        # radar chart dasar

data_single <- data.frame(
  Komunikasi   = c(10, 0, 8),
  Kepemimpinan = c(10, 0, 6),
  Analisis     = c(10, 0, 9),
  Kreativitas  = c(10, 0, 7),
  Kolaborasi   = c(10, 0, 5)
)
rownames(data_single) <- c("Max", "Min", "Profil A")

radarchart(
  data_single,
  axistype    = 1,
  pcol        = rgb(0.2, 0.5, 0.8, 0.9),
  pfcol       = rgb(0.2, 0.5, 0.8, 0.35),
  plwd        = 3,
  cglcol      = "grey70",
  cglty       = 1,
  cglwd       = 0.8,
  axislabcol  = "black",
  caxislabels = seq(0, 10, 2),
  vlcex       = 0.9,
  title       = "Radar Chart – Profil A"
)

data_multi <- data.frame(
  Komunikasi   = c(10, 0, 8, 6, 7),
  Kepemimpinan = c(10, 0, 6, 9, 5),
  Analisis     = c(10, 0, 9, 7, 6),
  Kreativitas  = c(10, 0, 7, 8, 5),
  Kolaborasi   = c(10, 0, 5, 7, 8)
)
rownames(data_multi) <- c("Max", "Min", "Orang A", "Orang B", "Orang C")

radarchart(
  data_multi,
  axistype    = 1,
  pcol        = c("#e41a1c", "#377eb8", "#4daf4a"),
  pfcol       = c(
    rgb(228/255, 26/255, 28/255, 0.3),
    rgb(55/255,  126/255, 184/255, 0.3),
    rgb(77/255,  175/255, 74/255, 0.3)
  ),
  plwd        = 2,
  cglcol      = "grey70",
  cglty       = 1,
  cglwd       = 0.8,
  axislabcol  = "black",
  caxislabels = seq(0, 10, 2),
  vlcex       = 0.85,
  title       = "Radar Chart – Perbandingan Tiga Profil"
)
legend("topright",
       legend = c("Orang A", "Orang B", "Orang C"),
       bty = "n",
       pch = 20,
       col = c("#e41a1c", "#377eb8", "#4daf4a"),
       text.col = "black", cex = 0.9)