The following plot shows [Core Web Vital](https://web.dev/vitals/) metric results from users loading pages on [noisetosignal.io](https://www.noisetosignal.io/). Their metrics are pushed to GA using the process described in [this blog post](https://www.noisetosignal.io/2020/05/add-web-vitals-to-google-analytics/) and retrieved from GA using the code in this R Markdown file.

```{r echo=FALSE,message=FALSE,warning=FALSE}

knitr::opts_chunk$set(
  echo = FALSE,
  collapse = TRUE,
  message = FALSE,
  warning = FALSE,
  out.width = "70%",
  fig.align = 'center',
  fig.width = 7,
  fig.asp = 0.618,  # 1 / phi
  fig.show = "hold"
)
library(tidyverse)
library(googleAuthR)
library(showtext)
library(stringr)
# This only needs to run once per session
font_add_google("Roboto", "roboto")
showtext_auto()
library(rmarkdown)
options(
  gargle_oauth_cache = "/config",
  googleAuthR.scopes.selected = "https://www.googleapis.com/auth/analytics.readonly"
)
# Service Account Credentials
#gar_auth_service(json_file=Sys.getenv("SERVICE_JSON_NTS"))
gar_set_client(json = Sys.getenv("CLIENT_JSON_NTS_NO_ORG"))
gar_auth(email=Sys.getenv("CLIENT_EMAIL_NTS"))
library(googleAnalyticsR)

theme_set(theme_minimal())

# Select an account ID and view ID to begin
account_id <- 62965925 # NtS GA Account
view_id <- 105540599 # NtS Main view
```

```{r}

# Filter to retrieve only web vital events
vitals_filter <- filter_clause_ga4(list(dim_filter(dimension = "eventCategory",operator = "EXACT", expressions = "Web Vital Reporting")))

# Retrieve vital metric data from GA events
ga <- google_analytics(viewId = view_id, 
                       date_range = c(Sys.Date()-30,Sys.Date()),
                       metrics = c("eventValue"),
                       max = -1,
                       dimensions = c("eventAction","eventLabel","deviceCategory"),
                       dim_filters = vitals_filter) %>% mutate(eventValue = eventValue / 1000.0) %>%
  mutate(deviceCategory = forcats::fct_recode(deviceCategory,Desktop="desktop",Mobile="mobile")) %>% rename(Metric=eventAction) %>%
  # Dropping tablet to simplify reporting
  filter(deviceCategory != "tablet")


# Calculate percentiles for each metric and device type
percentiles <- ga %>% group_by(deviceCategory,Metric)  %>% summarise(eventValue = quantile(eventValue,.75))

# Experience thresholds are different for each metric
thresholds <- data.frame(Metric=rep(c("CLS","FID","LCP"),3), 
                         quality=c(rep("Good",3),rep("Needs Improvement",3),rep("Poor",3)),
                         fill_color=c(rep("#59A14F",3),rep("#F28E2B",3),rep("#E15759",3)),
                         start=c(0, 0, 0, .1, .1, 2.5, .25, .3, 4),
                         end=c(.1, .1, 2.5, .25, .3, 4, Inf, Inf, Inf))

ggplot(ga) + geom_histogram(aes(x=eventValue),bins=20) + 
  facet_grid(deviceCategory ~ Metric,scales = "free") +
  geom_rect(aes(xmin=start,xmax=end,fill=quality),ymin=0,ymax=Inf,alpha=.25,data=thresholds) + 
  scale_fill_manual(name = "Experience", values = c("Good" = "#59A14F","Needs Improvement"="#F28E2B","Poor"="#E15759")) +
  geom_vline(aes(xintercept=eventValue,color="75th Percentile"),linetype=3,size=1,data=percentiles) +
  scale_color_manual(name = "", values = c(`75th Percentile` = "black")) +
  theme(legend.position="right",
        text=element_text(size=12,  family="roboto"),
        axis.title.y = element_text(margin = margin(r = 10,unit = "pt")),
        axis.title.x = element_text(margin = margin(t = 10,unit = "pt")),
        plot.margin = margin(.5, 1.5,.5,.5,unit = "cm")
        ) + 
  scale_x_continuous(labels=scales::number_format(accuracy = .01)) + 
  labs(title="Core Web Vitals",x="Value",y="Count")

```

