# Chapter 12 Temporal

In the previous chapter we built a graph with dynamic edges. Let’s build a fully dynamic graph where both nodes and edges appear when they are first created.

## 12.1 Collect

We again collect tweets in a slightly different manner but feel free to use data from a previous chapter. We specify type as mixed in order to get a mix of popular and recent tweets.

# TK <- readRDS(file = "token.rds")
tweets <- search_tweets("#rstats filter:mentions", n = 1000, token = TK, include_rts = FALSE, type = "mixed")
## Searching for tweets...
## Finished collecting tweets!

## 12.2 Build

We build the graph as we did in the previous chapter.

net <- tweets %>%
gt_edges(screen_name, mentions_screen_name, created_at) %>%
gt_nodes() %>%
gt_dyn() %>%
gt_collect()

## 12.3 Visualise

Again, we unpack the network and prepare nodes and edges for our visualisation. Then we define a rescale functiion to ensure our treatment of the date time columns are consistent across nodes and edges.

c(edges, nodes) %<-% net

#' @param x Date time column.
#' @param t Number of milliseconds to rescale to.
rescale <- function(x, t){
x <- as.numeric(x)
x <-  (x - min(x)) / (max(x) - min(x))
x <- x * t
return(x)
}

rtweet returns date time but sigmajs expects milliseconds; it needs to be converted.

Next we prepare the data, we define the t argument of our rescale function defined above as a constant so as to make sure we apply the same scale to both nodes and edges.

library(dplyr)

T <- 10000

lockBinding("T", globalenv())

nodes <- nodes %>%
nodes2sg() %>%
mutate(
start = rescale(start, T)
) %>%
select(id, label, size, start)

edges <- edges %>%
mutate(
id = 1:n(),
created_at = as.numeric(created_at),
created_at = rescale(created_at, T)
) %>%
select(id, source, target, created_at)

Now the actual visualisation, then again, we set cumsum = FALSE, and add a button (linked to two events add_nodes and add_edges) to let you trigger the visualisation. before then you should see a blank canvas.

sigmajs() %>%
sg_add_nodes(nodes, start, id, label, size, cumsum = FALSE) %>%
sg_add_edges(edges, created_at, id, source, target, cumsum = FALSE) %>%
sg_button("Start", c("add_nodes", "add_edges"))

We forgot the layout and we do not color the nodes, let’s compute the layout and the clusters to color nodes.

nodes <- sg_get_layout(nodes, edges)

nodes <- sg_get_cluster(
nodes,
edges,
colors = c(
"#0084b4",
"#00aced",
"#1dcaff",
"#c0deed"
)
)
## Found # 325 clusters
sigmajs() %>%
sg_add_nodes(nodes, start, id, label, size, color, x, y, cumsum = FALSE) %>%
sg_add_edges(edges, created_at, id, source, target, cumsum = FALSE) %>%
sg_button("Start", c("add_nodes", "add_edges"))

So we transformed our date time to milliseconds and rescaled to span 10 seconds. The problem with this is that we, in a way, lose track of time in the visualisation itself. It’d be great to add a ticker to display, say, the date.

Let’s explain how this is done in sigmajs; we simply create a table that maps dates to our milliseconds delay. To do so we extract the dates from our net object, we then rescale those dates just like we did for the nodes and edges.

dates <- as.Date(net$nodes$start)

ticker <- dplyr::tibble(
dates = dates,
delay = rescale(dates, T)
) %>%
arrange(delay)

head(ticker)
dates delay
2018-08-06 0.0000
2018-08-07 749.5644
2018-08-08 1810.6870
2018-08-09 2724.6452
2018-08-10 3723.9730
2018-08-11 4691.6773

Now, how do we use this mapping table in sigmajs?

sigmajs() %>%
sg_add_nodes(nodes, start, id, label, size, color, x, y, cumsum = FALSE) %>%
sg_add_edges(edges, created_at, id, source, target, cumsum = FALSE) %>%
sg_progress(ticker, delay, dates, cumsum = FALSE) %>%
sg_settings(
edgeColor = "default",
defaultEdgeColor = "#d3d3d3"
) %>%
sg_button("Start", c("add_nodes", "add_edges"))