---
title: "CRAN Download Monitor"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    social: menu
    source_code: https://git.io/vaZdx
runtime: shiny
---

```{r setup, include=FALSE}
library(flexdashboard)

# Access to CRAN packages data stream
source("package_stream.R")

# pkgStream is a reactive expression that represents a stream of
# new package download data; up to once a second it may return a
# data frame of new downloads since the last update.
pkgStream <- packageStream()

# pkgData is a reactive expression that accumulates previous values
# of pkgStream, discarding any that are older than maxAgeSecs.
maxAgeSecs <- 60 * 5 
pkgData <- packageData(pkgStream, maxAgeSecs)
```

Sidebar {.sidebar}
=======================================================================

### cran.rstudio.com

The streaming data is a 1-week-delayed livestream of download
logs from  cran.rstudio.com. The server code for that service is at [jcheng5/cransim](https://github.com/jcheng5/cransim).


```{r}
# Rate at which to flag high download traffic
sliderInput("rateThreshold", "Warn when rate exceeds:",
            min = 0, max = 50, value = 3, step = 0.1
)

# Maximum number of raw data rows to keep
numericInput("maxrows", "Recent downloads window:", 50)
```


Dashboard
=======================================================================

Row
-----------------------------------------------------------------------

### Downloads per sec (last 5 min) {.value-box}

```{r}
# downloadRate is a reactive expression that computes the download
# rate during this dashboard's lifetime.
startTime <- as.numeric(Sys.time())
downloadRate <- reactive({
  elapsed <- as.numeric(Sys.time()) - startTime
  nrow(pkgData()) / min(maxAgeSecs, elapsed)
})

# Emit the download rate
renderValueBox({
  rate <- formatC(downloadRate(), digits = 1, format = "f")
  valueBox(
    value = rate,
    icon = "fa-area-chart",
    color = if (rate >= input$rateThreshold) "warning" else "primary"
  )
})
```

### Total downloads {.value-box}

```{r}
# dlCount is a reactive expression that keeps track of the total
# number of rows that have ever appeared through pkgStream.
dlCount <- downloadCount(pkgStream)

# Emit the download count
renderValueBox({
  valueBox(dlCount(), icon = "fa-download")
})
```

### Unique users {.value-box}

```{r}
# usrCount is a reactive expression that keeps an approximate
# count of all of the unique users that have been seen since the
# app started.
usrCount <- userCount(pkgStream)

# Emit the user count
renderValueBox({
  valueBox(value = usrCount(), icon = "fa-users")
})
```

Row
-----------------------------------------------------------------------

### Popularity by package (last 5 min) {data-width=700}

```{r}
renderBubbles({
  if (nrow(pkgData()) == 0)
    return()

  order <- unique(pkgData()$package)
  df <- pkgData() %>%
    group_by(package) %>%
    tally() %>%
    arrange(desc(n), tolower(package)) %>%
    # Just show the top 60, otherwise it gets hard to see
    head(60)

  bubbles(df$n, df$package, key = df$package)
})
```

### Percent of downloads (last 5 min) {data-width=340}

```{r}
renderTable({
  pkgData() %>%
    group_by(package) %>%
    tally() %>%
    arrange(desc(n), tolower(package)) %>%
    mutate(percentage = n / nrow(pkgData()) * 100) %>%
    select("Package" = package, "Percent" = percentage) %>%
    as.data.frame() %>%
    head(30)
}, digits = 1)

```

Recent Downloads
=======================================================================

### Recent Downlads

```{r}
renderTable({
  downloads <- tail(pkgData(), n = input$maxrows)
  downloads <- downloads[,c("date", "time", "size", "r_version", 
                            "r_arch", "r_os", "package")]
  downloads[order(nrow(downloads):1),]
})
```

