The Colorado Report

A monthly review of the state of Colorado.

library(connectapi)
library(ggplot2)
library(dplyr)
library(janitor)
library(lubridate)
library(stringr)
library(scales)
library(forcats)
library(glue)


colour_mapping_lang <- c(
  "Python" = "#FFD43B",
  "R" = "#276BBE",
  "Quarto" = "#75AADB",
  "Unknown" = "#C4C7C9"
)

colour_mapping_type <- c(
  "Document" = "#447099",
  "Web App" = "#72994E",
  "API" = "#EE6331",
  "Unknown" = "#C4C7C9"
)
client <- connect()
content <- get_content(client)
content <- content |>
  # Classify content
  mutate(
    language = case_when(
      !is.na(r_version) ~ "R",
      !is.na(py_version) ~ "Python",
      !is.na(quarto_version) ~ "Quarto",
      TRUE ~ "Unknown"
    ),
    app_type = case_when(
      str_ends(app_mode, "static") ~ "Document",
      str_ends(app_mode, "api") ~ "API",
      str_ends(app_mode, "shiny") ~ "Web App",
      str_ends(app_mode, "streamlit") ~ "Web App",
      str_ends(app_mode, "bokeh") ~ "Web App",
      str_ends(app_mode, "dash") ~ "Web App",
      TRUE ~ "Unknown"
    )
  ) |> 
  # Orgnize factors
  mutate(
    language = factor(language, levels = c("Unknown", "QUarto", "Python", "R")),
    app_type = factor(app_type, levels = c("Unknown", "API", "Web App", "Document"))
  )
licensed_users <- client |> 
  get_users(page_size = 50, limit = 99999) |>
  filter(locked == FALSE)

summary_of_last_login <- licensed_users |> 
  mutate(
    last_active_month = as.Date(lubridate::floor_date(active_time, unit = "month")),
  ) |> 
  group_by(last_active_month) |>
  summarise(count = n(), .groups = "drop") |> 
  arrange(desc(last_active_month))

last_year <- lubridate::today() - days(365)

num_not_logged_in_1_year <- summary_of_last_login |>
  filter(last_active_month < last_year) |>
  nrow()

Users

Colorado has 341 licensed users. Of those 341 users, 48 have not logged in for a year.

Code
usage_plot <- summary_of_last_login |>
  ggplot(aes(x = last_active_month, y = count)) +
  geom_line() +
  geom_vline(xintercept = last_year, color="red") +
  annotate(
    "rect", 
    xmin=min(summary_of_last_login$last_active_month), 
    xmax=last_year, 
    ymin=0, 
    ymax=max(summary_of_last_login$count), 
    alpha=.2, 
    fill='red'
  ) +
  annotate(
    "label", 
    x =last_year,
    hjust=1.1,
    y=max(summary_of_last_login$count) / 2,
    label=glue("{num_not_logged_in_1_year} users have not logged in for a year"),
    color="red"
  ) +
  labs(
    title = "Last Login",
    subtitle = "Count of users by last login (licensed users only).",
    x = "Month",
    y = "Number of Users",
  )
  
usage_plot

Content

Colorado has 6,946 items deployed.

Code
deployed_by_language <- content |> 
  group_by(language, app_type) |>
  summarise(n = n(), .groups = "drop") |> 
  ggplot(aes(x = app_type, y = n)) +
  geom_col(aes(fill = language)) +
  scale_fill_manual(values = colour_mapping_lang) +
  scale_y_continuous(label=comma) +
  labs(
    title = "Distribution of Content Deployed on Colorado",
    subtitle = "By Langauge and Type",
    x = "Type",
    y = "Count",
    fill = "Language"
  ) +
  coord_flip()

deployed_by_language

Code
content |> 
  tabyl(app_mode) |> 
  arrange(desc(n)) |> 
  mutate(app_mode = fct_reorder(factor(app_mode), n)) |> 
  ggplot(aes(x = app_mode, y = n)) +
  geom_col() +
  geom_label(aes(label = percent(percent, accuracy = 1)), nudge_y = 100) +
  scale_y_continuous(label=comma) +
  labs(
    title = "Distribution of Content Deployed on Colorado",
    subtitle = "By App Mode",
    x = "App Mode",
    y = "Count"
  ) +
  coord_flip()

We can see how the type of content deployed changes over time.

Code
content |> 
  mutate(create_year_month = floor_date(created_time, unit = "month")) |> 
  group_by(language, create_year_month) |> 
  summarise(count = n(), .groups = "drop") |> 
  ggplot(aes(x = create_year_month, y = count)) +
  geom_col(aes(fill = language)) + 
  scale_fill_manual(values = colour_mapping_lang) + 
  scale_y_continuous(label=comma) +
  labs(
    title = "Content Creation Over Time",
    subtitle = "By langauge",
    x = "Month",
    y = "Count",
    fill = "Language"
  )

Code
content |> 
  mutate(create_year_month = floor_date(created_time, unit = "month")) |> 
  group_by(app_type, create_year_month) |> 
  summarise(count = n(), .groups = "drop") |> 
  ggplot(aes(x = create_year_month, y = count)) +
  geom_col(aes(fill = app_type)) + 
  scale_fill_manual(values = colour_mapping_type) +
  scale_y_continuous(label=comma) +
  labs(
    title = "Content Creation Over Time",
    subtitle = "By app type",
    x = "Month",
    y = "Count",
    fill = "App Type"
  )