OliverKeyes has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/239858

Change subject: Switch Rainbow over to Polloi
......................................................................

Switch Rainbow over to Polloi

Switches the Rainbow dashboards over to use Polloi for common
functionality rather than relying on local versions.

Bug: T112700
Change-Id: I421532aac2c43b077a2afae476358ade3a73f551
---
D assets/css/custom.css
M server.R
M utils.R
3 files changed, 152 insertions(+), 287 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/wikimedia/discovery/rainbow 
refs/changes/58/239858/1

diff --git a/assets/css/custom.css b/assets/css/custom.css
deleted file mode 100644
index fb0d105..0000000
--- a/assets/css/custom.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.dygraph-legend {
-  background-color: #ECF0F5 !important;
-}
diff --git a/server.R b/server.R
index 932ea65..8144ec3 100644
--- a/server.R
+++ b/server.R
@@ -6,30 +6,30 @@
 ## Read in desktop data and generate means for the value boxes, along with a 
time-series appropriate form for
 ## dygraphs.
 read_desktop <- function(){
-  data <- download_set("desktop_event_counts.tsv")
+  data <- polloi::read_dataset("search/desktop_event_counts.tsv")
   interim <- reshape2::dcast(data, formula = timestamp ~ action, fun.aggregate 
= sum)
   interim[is.na(interim)] <- 0
   desktop_dygraph_set <<- interim
   desktop_dygraph_means <<- round(colMeans(desktop_dygraph_set[,2:5]))
 
-  data <- download_set("desktop_load_times.tsv")
+  data <- polloi::read_dataset("search/desktop_load_times.tsv")
   desktop_load_data <<- data
   return(invisible())
 }
 
 read_web <- function(){
-  data <- download_set("mobile_event_counts.tsv")
+  data <- polloi::read_dataset("search/mobile_event_counts.tsv")
   interim <- reshape2::dcast(data, formula = timestamp ~ action, fun.aggregate 
= sum)
   interim[is.na(interim)] <- 0
   mobile_dygraph_set <<- interim
   mobile_dygraph_means <<- round(colMeans(mobile_dygraph_set[,2:4]))
 
-  mobile_load_data <<- download_set("mobile_load_times.tsv")
+  mobile_load_data <<- polloi::read_dataset("search/mobile_load_times.tsv")
   return(invisible())
 }
 
 read_apps <- function(){
-  data <- download_set("app_event_counts.tsv")
+  data <- polloi::read_dataset("search/app_event_counts.tsv")
 
   ios <- reshape2::dcast(data[data$platform == "iOS",], formula = timestamp ~ 
action, fun.aggregate = sum)
   android <- reshape2::dcast(data[data$platform == "Android",], formula = 
timestamp ~ action, fun.aggregate = sum)
@@ -39,7 +39,7 @@
   android_dygraph_set <<- android
   android_dygraph_means <<- round(colMeans(android[,2:4]))
 
-  app_load_data <- download_set("app_load_times.tsv")
+  app_load_data <- polloi::read_dataset("search/app_load_times.tsv")
   ios_load_data <<- app_load_data[app_load_data$platform == "iOS", 
names(app_load_data) != "platform"]
   android_load_data <<- app_load_data[app_load_data$platform == "Android", 
names(app_load_data) != "platform"]
 
@@ -47,14 +47,14 @@
 }
 
 read_api <- function(){
-  data <- download_set("search_api_aggregates.tsv")
+  data <- polloi::read_dataset("search/search_api_aggregates.tsv")
   data <- data[order(data$event_type),]
   split_dataset <<- split(data, f = data$event_type)
   return(invisible())
 }
 
 read_failures <- function(date){
-  data <- download_set("cirrus_query_aggregates.tsv")
+  data <- polloi::read_dataset("search/cirrus_query_aggregates.tsv")
   interim_data <- reshape2::dcast(data, formula = date ~ variable, 
fun.aggregate = sum)
   failure_dygraph_set <<- interim_data
 
@@ -66,12 +66,12 @@
                                          daily_change = output_vector*100,
                                          stringsAsFactors = FALSE)
 
-  interim_breakdown_data <- download_set("cirrus_query_breakdowns.tsv")
+  interim_breakdown_data <- 
polloi::read_dataset("search/cirrus_query_breakdowns.tsv")
   interim_breakdown_data$value <- interim_breakdown_data$value*100
   failure_breakdown_dygraph_set <<- reshape2::dcast(interim_breakdown_data,
                                                     formula = date ~ variable, 
fun.aggregate = sum)
 
-  suggestion_data <- download_set("cirrus_suggestion_breakdown.tsv")
+  suggestion_data <- 
polloi::read_dataset("search/cirrus_suggestion_breakdown.tsv")
   suggestion_data$variable <- "Full-Text with Suggestions"
   suggestion_data$value <- suggestion_data$value*100
   suggestion_data <- rbind(suggestion_data,
@@ -123,17 +123,18 @@
 
   ## The dynamic graphs of events on desktop
   output$desktop_event_plot <- renderDygraph({
-    smooth_level <- input$smoothing_desktop_event
-    make_dygraph(desktop_dygraph_set,
-                 "Date", "Events", "Desktop search events, by day",
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(desktop_dygraph_set,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_desktop_event)),
+                         xlab = "Date", ylab = "Events", title = "Desktop 
search events, by day")
   })
+
   output$desktop_load_plot <- renderDygraph({
-    smooth_level <- input$smoothing_desktop_load
-    make_dygraph(desktop_load_data,
-                 "Date", "Load time (ms)", "Desktop result load times, by day",
-                 use_si = FALSE,
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(desktop_load_data,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_desktop_load)),
+                         xlab = "Date", ylab = "Load time (ms)", title = 
"Desktop load times, by day",
+                         use_si = FALSE)
   })
 
   ## Mobile value boxes
@@ -166,14 +167,18 @@
 
   ## Mobile plots
   output$mobile_event_plot <- renderDygraph({
-    smooth_level <- input$smoothing_mobile_event
-    make_dygraph(mobile_dygraph_set, "Date", "Events", "Mobile search events, 
by day",
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(mobile_dygraph_set,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_mobile_event)),
+                         xlab = "Date", ylab = "Events", title = "Mobile 
search events, by day")
   })
+
   output$mobile_load_plot <- renderDygraph({
-    smooth_level <- input$smoothing_mobile_load
-    make_dygraph(mobile_load_data, "Date", "Load time (ms)", "Mobile result 
load times, by day",
-                 use_si = FALSE, smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(mobile_load_data,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_mobile_load)),
+                         xlab = "Date", ylab = "Load time (ms)", "Mobile 
result load times, by day",
+                         use_si = FALSE)
   })
 
   ## App value boxes
@@ -206,73 +211,104 @@
 
   ## App plots
   output$android_event_plot <- renderDygraph({
-    smooth_level <- input$smoothing_app_event
-    make_dygraph(android_dygraph_set, "Date", "Events", "Android mobile app 
search events, by day",
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(android_dygraph_set,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_app_event)),
+                         xlab = "Date", ylab = "Events", "Android mobile app 
search events, by day")
   })
+
   output$android_load_plot <- renderDygraph({
-    smooth_level <- input$smoothing_app_load
-    make_dygraph(android_load_data, "Date", "Load time (ms)","Android result 
load times, by day", use_si = FALSE,
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(android_load_data,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_app_load)),
+                         xlab = "Date", ylab = "Load time (ms)", "Android 
result load times, by day",
+                         use_si = FALSE)
   })
+
   output$ios_event_plot <- renderDygraph({
-    smooth_level <- input$smoothing_app_event
-    make_dygraph(ios_dygraph_set, "Date", "Events","iOS mobile app search 
events, by day",
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(ios_dygraph_set,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_app_event)),
+                         xlab = "Date", ylab = "Events", "iOS mobile app 
search events, by day")
   })
+
   output$ios_load_plot <- renderDygraph({
-    smooth_level <- input$smoothing_app_load
-    make_dygraph(ios_load_data, "Date", "Load time (ms)","iOS result load 
times, by day", use_si = FALSE,
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(ios_load_data,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_app_load)),
+                         xlab = "Date", ylab = "Load time (ms)", "iOS result 
load times, by day",
+                         use_si = FALSE)
   })
 
   ## API plots
   output$cirrus_aggregate <- renderDygraph({
-    smooth_level <- input$smoothing_fulltext_search
-    make_dygraph(split_dataset$cirrus, "Date", "Events", "Full-text via API 
usage by day", TRUE,
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
-  })
-  output$open_aggregate <- renderDygraph({
-    smooth_level <- input$smoothing_open_search
-    make_dygraph(split_dataset$open, "Date", "Events", "OpenSearch API usage 
by day", TRUE,
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
-  })
-  output$geo_aggregate <- renderDygraph({
-    smooth_level <- input$smoothing_geo_search
-    make_dygraph(split_dataset$geo, "Date", "Events", "Geo Search API usage by 
day", TRUE,
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
-  })
-  output$language_aggregate <- renderDygraph({
-    smooth_level <- input$smoothing_language_search
-    make_dygraph(split_dataset$language, "Date", "Events", "Language Search 
API usage by day", TRUE,
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
-  })
-  output$prefix_aggregate <- renderDygraph({
-    smooth_level <- input$smoothing_prefix_search
-    make_dygraph(split_dataset$prefix, "Date", "Events", "Prefix Search API 
usage by day", TRUE,
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(split_dataset$cirrus[,c(1,3)],
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_fulltext_search)),
+                         xlab = "Date", ylab = "Searches", "Full-text via API 
usage by day",
+                         legend_name = "Searches")
   })
 
-  ## Failure plots
+  output$open_aggregate <- renderDygraph({
+    polloi::make_dygraph(data = polloi::smoother(split_dataset$open[,c(1,3)],
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_open_search)),
+                         xlab = "Date", ylab = "Searches", "OpenSearch API 
usage by day",
+                         legend_name = "Searches")
+  })
+
+  output$geo_aggregate <- renderDygraph({
+    polloi::make_dygraph(data = polloi::smoother(split_dataset$geo[,c(1,3)],
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_geo_search)),
+                         xlab = "Date", ylab = "Searches", "Geo Search API 
usage by day",
+                         legend_name = "Searches")
+  })
+
+  output$language_aggregate <- renderDygraph({
+    polloi::make_dygraph(data = 
polloi::smoother(split_dataset$language[,c(1,3)],
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_language_search)),
+                         xlab = "Date", ylab = "Searches", "Language Search 
API usage by day",
+                         legend_name = "Searches")
+  })
+
+  output$prefix_aggregate <- renderDygraph({
+    polloi::make_dygraph(data = polloi::smoother(split_dataset$prefix[,c(1,3)],
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_prefix_search)),
+                         xlab = "Date", ylab = "Searches", "Prefix Search API 
usage by day",
+                         legend_name = "Searches")
+  })
+
+  # Failure plots
   output$failure_rate_plot <- renderDygraph({
-    smooth_level <- input$smoothing_failure_rate
-    make_dygraph(failure_dygraph_set, "Date", "Queries", "Search Queries with 
Zero Results, by day",
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(failure_dygraph_set,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_failure_rate)),
+                         xlab = "Date", ylab = "Queries", "Search Queries with 
Zero Results, by day")
   })
+
   output$failure_rate_change_plot <- renderDygraph({
-    smooth_level <- input$smoothing_failure_rate
-    make_dygraph(failure_roc_dygraph_set, "Date", "Change (%)", "Zero result 
rate change, by day", TRUE, "Rate of Change",
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = 
polloi::smoother(failure_roc_dygraph_set[,c(1,3)],
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_failure_rate)),
+                         xlab = "Date", ylab = "Change (%)", "Zero Results 
rate change, by day",
+                         legend_name = "Change")
   })
+
   output$failure_breakdown_plot <- renderDygraph({
-    smooth_level <- input$smoothing_failure_breakdown
-    make_dygraph(failure_breakdown_dygraph_set, "Date", "Zero Results Rate 
(%)", "Zero result rate by search type",
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(failure_breakdown_dygraph_set,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_failure_breakdown)),
+                         xlab = "Date", ylab = "Zero Results Rate (%)", "Zero 
result rate by search type")
   })
+
   output$suggestion_dygraph_plot <- renderDygraph({
-    smooth_level <- input$smoothing_failure_suggestions
-    make_dygraph(suggestion_dygraph_set, "Date", "Zero Results Rate (%)", 
"Zero Result Rates with Search Suggestions",
-                 smoothing = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level))
+    polloi::make_dygraph(data = polloi::smoother(suggestion_dygraph_set,
+                                         smooth_level = 
polloi::smooth_switch(input$smoothing_global,
+                                                                              
input$smoothing_failure_suggestions)),
+                         xlab = "Date", ylab = "Zero Results Rate (%)", "Zero 
Result Rates with Search Suggestions")
   })
 
   ## KPI module
@@ -280,7 +316,7 @@
     date_range <- input$kpi_summary_date_range_selector
     switch(date_range,
            daily = {
-             temp <- safe_tail(desktop_load_data, 2)$timestamp %>% {
+             temp <- polloi::safe_tail(desktop_load_data, 2)$timestamp %>% {
                paste0(as.character(., "%A, %b "),
                       sub("([a-z]{2})", "<sup>\\1</sup>",
                           sapply(as.numeric(as.character(., "%e")), 
toOrdinal)))
@@ -288,7 +324,7 @@
            },
            weekly = {
              date_range_index <- c(1, 7, 8, 14)
-             temp <- safe_tail(desktop_load_data, 
date_range_index[4])$timestamp %>% {
+             temp <- polloi::safe_tail(desktop_load_data, 
date_range_index[4])$timestamp %>% {
                paste0(as.character(.[date_range_index], "%b "),
                       sub("([a-z]{2})", "<sup>\\1</sup>",
                           sapply(as.numeric(as.character(.[date_range_index], 
"%e")), toOrdinal)))
@@ -298,7 +334,7 @@
            },
            monthly = {
              date_range_index <- c(1, 31, 31, 60)
-             temp <- safe_tail(desktop_load_data, 
date_range_index[4])$timestamp %>% {
+             temp <- polloi::safe_tail(desktop_load_data, 
date_range_index[4])$timestamp %>% {
                paste0(as.character(.[date_range_index], "%b "),
                       sub("([a-z]{2})", "<sup>\\1</sup>",
                           sapply(as.numeric(as.character(.[date_range_index], 
"%e")), toOrdinal)))
@@ -308,7 +344,7 @@
            },
            quarterly = {
              date_range_index <- c(1, 90)
-             temp <- safe_tail(desktop_load_data, 
date_range_index[2])$timestamp %>% {
+             temp <- polloi::safe_tail(desktop_load_data, 
date_range_index[2])$timestamp %>% {
                paste0(as.character(.[date_range_index], "%B "),
                       sub("([a-z]{2})", "<sup>\\1</sup>",
                           sapply(as.numeric(as.character(.[date_range_index], 
"%e")), toOrdinal)))
@@ -323,7 +359,7 @@
            daily = {
              x <- lapply(list(desktop_load_data, mobile_load_data,
                               android_load_data, ios_load_data),
-                         safe_tail, n = 2) %>%
+                         polloi::safe_tail, n = 2) %>%
                lapply(function(data_tail) return(data_tail$Median)) %>%
                do.call(cbind, .) %>%
                apply(MARGIN = 1, FUN = median)
@@ -331,7 +367,7 @@
            weekly = {
              x <- lapply(list(desktop_load_data, mobile_load_data,
                               android_load_data, ios_load_data),
-                         safe_tail, n = 14) %>%
+                         polloi::safe_tail, n = 14) %>%
                lapply(function(data_tail) return(data_tail$Median)) %>%
                do.call(cbind, .) %>%
                apply(MARGIN = 1, FUN = median)
@@ -339,7 +375,7 @@
            monthly = {
              x <- lapply(list(desktop_load_data, mobile_load_data,
                               android_load_data, ios_load_data),
-                         safe_tail, n = 60) %>%
+                         polloi::safe_tail, n = 60) %>%
                lapply(function(data_tail) return(data_tail$Median)) %>%
                do.call(cbind, .) %>%
                apply(MARGIN = 1, FUN = median)
@@ -347,37 +383,37 @@
            quarterly = {
              x <- lapply(list(desktop_load_data, mobile_load_data,
                               android_load_data, ios_load_data),
-                         safe_tail, n = 90) %>%
+                         polloi::safe_tail, n = 90) %>%
                lapply(function(data_tail) return(data_tail$Median))
              y <- median(apply(do.call(cbind, x), 1, median))
              return(valueBox(subtitle = "Load time", value = sprintf("%.0fms", 
y), color = "orange"))
            })
-    y1 <- median(half(x, "top")); y2 <- median(half(x, "bottom")); z <- 100 * 
(y2 - y1) / y1
+    y1 <- median(polloi::half(x)); y2 <- median(polloi::half(x, FALSE)); z <- 
100 * (y2 - y1) / y1
     if (abs(z) > 0) {
       return(valueBox(subtitle = sprintf("Load time (%.1f%%)", z),
                       value = sprintf("%.0fms", y2),
-                      color = cond_color(z>0, "red"), icon = cond_icon(z>0)))
+                      color = polloi::cond_color(z > 0, "red"), icon = 
polloi::cond_icon(z > 0)))
     }
     return(valueBox(subtitle = "Load time (no change)", value = 
sprintf("%.0fms", y2), color = "orange"))
   })
   output$kpi_summary_box_zero_results <- renderValueBox({
     date_range <- input$kpi_summary_date_range_selector
     switch(date_range,
-           daily = {x <- safe_tail(failure_dygraph_set, 2)},
-           weekly = {x <- safe_tail(failure_dygraph_set, 14)},
-           monthly = {x <- safe_tail(failure_dygraph_set, 60)},
-           quarterly = {x <- safe_tail(failure_dygraph_set, 90)})
+           daily = {x <- polloi::safe_tail(failure_dygraph_set, 2)},
+           weekly = {x <- polloi::safe_tail(failure_dygraph_set, 14)},
+           monthly = {x <- polloi::safe_tail(failure_dygraph_set, 60)},
+           quarterly = {x <- polloi::safe_tail(failure_dygraph_set, 90)})
     x <- transform(x, Rate = `Zero Result Queries` / `Search Queries`)$Rate
     if (date_range == "quarterly") {
       return(valueBox(subtitle = "Zero results rate", color = "orange",
                       value = sprintf("%.1f%%", median(100 * x))))
     }
-    y1 <- median(half(x, "top")); y2 <- median(half(x, "bottom")); z <- 100 * 
(y2 - y1)/y1
+    y1 <- median(polloi::half(x)); y2 <- median(polloi::half(x, FALSE)); z <- 
100 * (y2 - y1)/y1
     if (abs(z) > 0) {
       return(valueBox(
         subtitle = sprintf("Zero results rate (%.1f%%)", z),
         value = sprintf("%.1f%%", 100 * y2),
-        icon = cond_icon(z > 0), color = cond_color(z > 0, "red")
+        icon = cond_icon(z > 0), color = polloi::cond_color(z > 0, "red")
       ))
     }
     return(valueBox(subtitle = "Zero results rate (no change)",
@@ -387,24 +423,24 @@
     date_range <- input$kpi_summary_date_range_selector
     x <- lapply(split_dataset, function(x) {
       switch(date_range,
-             daily = { safe_tail(x, 2)$events },
-             weekly = { safe_tail(x, 14)$events },
-             monthly = { safe_tail(x, 60)$events },
-             quarterly = { safe_tail(x, 90)$events })
+             daily = { polloi::safe_tail(x, 2)$events },
+             weekly = { polloi::safe_tail(x, 14)$events },
+             monthly = { polloi::safe_tail(x, 60)$events },
+             quarterly = { polloi::safe_tail(x, 90)$events })
     }) %>% do.call(cbind, .) %>%
       transform(total = cirrus + geo + language + open + prefix) %>%
       { .$total }
     if (date_range == "quarterly") {
-      return(valueBox(subtitle = "API usage", value = compress(median(x), 0), 
color = "orange"))
+      return(valueBox(subtitle = "API usage", value = 
polloi::compress(median(x), 0), color = "orange"))
     }
-    y1 <- median(half(x, "top"))
-    y2 <- median(half(x, "bottom"))
+    y1 <- median(polloi::half(x, FALSE))
+    y2 <- median(polloi::half(x, FALSE))
     z <- 100 * (y2 - y1) / y1 # % change from t-1 to t
     if (abs(z) > 0) {
       return(valueBox(subtitle = sprintf("API usage (%.1f%%)", z),
-                      value = compress(y2, 0), color = cond_color(z>0), icon = 
cond_icon(z>0)))
+                      value = polloi::compress(y2, 0), color = 
polloi::cond_color(z > 0), icon = polloi::cond_icon(z > 0)))
     }
-    return(valueBox(subtitle = "API usage (no change)", value = compress(y2, 
0), color = "orange"))
+    return(valueBox(subtitle = "API usage (no change)", value = 
polloi::compress(y2, 0), color = "orange"))
   })
   output$kpi_summary_api_usage_proportions <- renderPlot({
     switch (input$kpi_summary_date_range_selector,
@@ -413,11 +449,11 @@
             monthly = { n <- 30 },
             quarterly = { n <- 90 }
     )
-    api_latest <- cbind("Full-text via API" = safe_tail(split_dataset$cirrus, 
n)$events,
-                        "Geo Search" = safe_tail(split_dataset$geo, n)$events,
-                        "OpenSearch" = safe_tail(split_dataset$open, n)$events,
-                        "Language" = safe_tail(split_dataset$language, 
n)$events,
-                        "Prefix" = safe_tail(split_dataset$prefix, n)$events) 
%>%
+    api_latest <- cbind("Full-text via API" = 
polloi::safe_tail(split_dataset$cirrus, n)$events,
+                        "Geo Search" = polloi::safe_tail(split_dataset$geo, 
n)$events,
+                        "OpenSearch" = polloi::safe_tail(split_dataset$open, 
n)$events,
+                        "Language" = polloi::safe_tail(split_dataset$language, 
n)$events,
+                        "Prefix" = polloi::safe_tail(split_dataset$prefix, 
n)$events) %>%
       apply(2, median) %>% round
     api_latest <- data.frame(API = names(api_latest),
                              Events = api_latest,
@@ -434,7 +470,7 @@
     smooth_level <- input$smoothing_kpi_load_time
     num_of_days_in_common <- min(sapply(list(desktop_load_data$Median, 
mobile_load_data$Median, android_load_data$Median, ios_load_data$Median), 
length))
     load_times <- list(desktop_load_data, mobile_load_data, android_load_data, 
ios_load_data) %>%
-      lapply(safe_tail, num_of_days_in_common) %>%
+      lapply(polloi::safe_tail, num_of_days_in_common) %>%
       lapply(function(data_tail) return(data_tail$Median)) %>%
       as.data.frame %>%
       { colnames(.) <- c("Desktop", "Mobile Web", "Android", "iOS"); . } %>%
@@ -442,8 +478,8 @@
         Median = apply(., 1, median)
         cbind(Median = Median, .)
       } %>%
-      cbind(timestamp = safe_tail(desktop_load_data, 
num_of_days_in_common)$timestamp, .) %>%
-      smoother(smooth_level = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level), rename = FALSE) %>%
+      cbind(timestamp = polloi::safe_tail(desktop_load_data, 
num_of_days_in_common)$timestamp, .) %>%
+      polloi::smoother(smooth_level = ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level), rename = FALSE) %>%
       { xts(.[, -1], order.by = .[, 1]) }
     return(dygraph(load_times,
                    main = "Load times over time",
@@ -463,7 +499,7 @@
     zrr <- 100 * failure_dygraph_set$`Zero Result Queries` / 
failure_dygraph_set$`Search Queries`
     zrr_change <- 100 * (zrr[2:length(zrr)] - 
zrr[1:(length(zrr)-1)])/zrr[1:(length(zrr)-1)]
     zrr <- data.frame(date = failure_dygraph_set$date[-1], rate = zrr[-1], 
change = zrr_change)
-    zrr %<>% smoother(ifelse(smooth_level == "global", input$smoothing_global, 
smooth_level), rename = FALSE)
+    zrr %<>% polloi::smoother(ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level), rename = FALSE)
     zrr <- xts(zrr[, -1], zrr[, 1])
     return(dygraph(zrr,
                    main = "Zero results rate over time",
@@ -496,7 +532,7 @@
       api_usage <- transform(api_usage, all = cirrus + geo + language + prefix)
     }
     if ( input$kpi_api_usage_series_data == "raw" ) {
-      api_usage %<>% smoother(ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level), rename = FALSE)
+      api_usage %<>% polloi::smoother(ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level), rename = FALSE)
       api_usage <- xts(api_usage[, -1], api_usage[, 1])
       if (!input$kpi_api_usage_series_include_open) {
         colnames(api_usage)[6] <- "all except open"
@@ -513,14 +549,14 @@
                dyCSS(css = "./assets/css/custom.css"))
     }
     api_usage_change <- transform(api_usage,
-                                  cirrus = percent_change(cirrus),
-                                  geo = percent_change(geo),
-                                  language = percent_change(language),
-                                  open = percent_change(open),
-                                  prefix = percent_change(prefix),
-                                  all = percent_change(all)) %>%
+                                  cirrus = polloi::percent_change(cirrus),
+                                  geo = polloi::percent_change(geo),
+                                  language = polloi::percent_change(language),
+                                  open = polloi::percent_change(open),
+                                  prefix = polloi::percent_change(prefix),
+                                  all = polloi::percent_change(all)) %>%
                                   { .[-1, ] }
-    api_usage_change %<>% smoother(ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level), rename = FALSE)
+    api_usage_change %<>% polloi::smoother(ifelse(smooth_level == "global", 
input$smoothing_global, smooth_level), rename = FALSE)
     api_usage_change <- xts(api_usage_change[, -1], api_usage_change[, 1])
     if (!input$kpi_api_usage_series_include_open) 
colnames(api_usage_change)[6] <- "all except open"
     return(dygraph(api_usage_change,
diff --git a/utils.R b/utils.R
index 882dad5..a20944a 100644
--- a/utils.R
+++ b/utils.R
@@ -1,142 +1,9 @@
 #Dependent libs
-library(plyr)
-library(readr)
-library(xts)
 library(reshape2)
-library(RColorBrewer)
 library(ggplot2)
 library(toOrdinal)
-library(lubridate)
 library(magrittr)
-
-#Utility functions for handling particularly common tasks
-download_set <- function(location){
-  location <- 
paste0("http://datasets.wikimedia.org/aggregate-datasets/search/";, location,
-                     "?ts=", gsub(x = Sys.time(), pattern = "(-| )", 
replacement = ""))
-  con <- url(location)
-  return(readr::read_delim(con, delim = "\t"))
-}
-
-# Takes an untidy (read: dygraph-appropriate) dataset and adds
-# columns for each variable consisting of the smoothed, averaged mean
-smoother <- function(dataset, smooth_level = "day", rename = TRUE) {
-
-  # Determine the names and levels of aggregation. By default
-  # a smoothing level of "day" is assumed, which is no smoothing
-  # whatsoever, and so the original dataset is returned.
-  switch(smooth_level,
-         moving_avg = {
-           df <- apply(dataset[, -1, drop = FALSE], 2, function(x) {
-             y <- xts(x, dataset[, 1])
-             return(as.numeric(zoo::rollmean(x, k = 17, fill = NA)))
-           }) %>% as.data.frame %>% cbind(timestamp = dataset[, 1], .)
-           names(df) <- names(dataset)
-           if (rename) names(df)[-1] <- paste(names(df)[-1], " (Moving 
average)")
-           return(df)
-         },
-         week = {
-           dataset$filter_1 <- lubridate::week(dataset[, 1])
-           dataset$filter_2 <- lubridate::year(dataset[, 1])
-           name_append <- ifelse(rename, " (Weekly average)", "")
-         },
-         month = {
-           dataset$filter_1 <- lubridate::month(dataset[, 1])
-           dataset$filter_2 <- lubridate::year(dataset[, 1])
-           name_append <- ifelse(rename, " (Monthly average)", "")
-         },
-         {
-           return(dataset)
-         }
-  )
-
-  # If we're still here it was weekly or monthly. Calculate
-  # the average for each unique permutation of filters
-
-  result <- ddply(.data = dataset,
-                  .variables = c("filter_1", "filter_2"),
-                  .fun = function(df, name_append){
-
-                    # Construct output names for the averages, compute those 
averages, and
-                    # apply said names.
-                    output_names <- paste0(names(df)[2:(ncol(df) - 2)], 
name_append)
-                    holding <- apply(df[, 2:(ncol(df) - 2), drop = FALSE], 2, 
FUN = median) %>%
-                      round %>% t %>% as.data.frame
-                    names(holding) <- output_names
-
-                    # Return the bound original values and averaged values
-                    return(cbind(df[, 1, drop = FALSE], holding))
-                  }, name_append = name_append)
-
-  return(result[, !(names(result) %in% c("filter_1","filter_2"))])
-}
-
-#Create a dygraph using our standard format.
-make_dygraph <- function(data, x, y, title, is_single = FALSE, legend_name = 
NULL, use_si = TRUE, smoothing = "day") {
-  # cat("Making dygraph:", title, "\n"); # Debugging
-  if (is_single) {
-    data <- smoother(as.data.frame(data[, c(1, 3)]), smooth_level = smoothing)
-    data <- xts(data[, 2], data[, 1])
-    if (is.null(legend_name)) {
-      names(data) <- "events"
-    } else {
-      names(data) <- legend_name
-    }
-  } else {
-    data %<>% smoother(smooth_level = smoothing)
-    data <- xts(data[, -1], order.by = data[, 1])
-  }
-  return(dygraph(data, main = title, xlab = x, ylab = y) %>%
-           dyLegend(width = 400, show = "always") %>%
-           dyOptions(strokeWidth = 3,
-                     colors = brewer.pal(max(3, ncol(data)), "Set2"),
-                     drawPoints = FALSE, pointSize = 3, labelsKMB = use_si,
-                     includeZero = TRUE) %>%
-           dyCSS(css = "./assets/css/custom.css"))
-}
-
-# Computes a median absolute deviation
-mad <- function(x) {
-  median(abs(x - median(x)))
-}
-
-compress <- function(x, round.by = 2) {
-  # by StackOverflow user 'BondedDust' : http://stackoverflow.com/a/28160474
-  div <- findInterval(as.numeric(gsub("\\,", "", x)),
-                      c(1, 1e3, 1e6, 1e9, 1e12) )
-  paste(round( as.numeric(gsub("\\,","",x))/10^(3*(div-1)), round.by),
-        c("","K","M","B","T")[div], sep = "" )
-}
-
-# Conditional icon for widget.
-# Returns arrow-up icon on true (if true_direction is 'up'), e.g. load time % 
change > 0
-cond_icon <- function(condition, true_direction = "up") {
-
-  if (true_direction == "up") {
-    return(icon(ifelse(condition, "arrow-up", "arrow-down")))
-  }
-
-  return(icon(ifelse(condition, "arrow-down", "arrow-up")))
-}
-
-# Conditional color for widget
-# Returns 'green' on true, 'red' on false, e.g. api usage % change > 0
-#                                               load time % change < 0
-cond_color <- function(condition, true_color = "green") {
-  if(is.na(condition)){
-    return("black")
-  }
-
-  colours <- c("green","red")
-  return(ifelse(condition, true_color, colours[!colours == true_color]))
-}
-
-# Allows very quickly to get half a vector:
-half <- function(x, which = c("top", "bottom")) {
-  if (which == "top") {
-    return(head(x, n = length(x)/2))
-  }
-  return(tail(x, n = length(x)/2))
-}
+library(polloi)
 
 # Uses ggplot2 to create a pie chart in bar form. (Will look up actual name)
 gg_prop_bar <- function(data, cols) {
@@ -158,39 +25,4 @@
     geom_text(aes_string(label = cols$label,
                   y = "text_position",
                   x = 1))
-}
-
-# Calculates percent change either in `x` or from `x` to `y`
-percent_change <- function(x, y = NULL) {
-  if(is.null(y)) {
-    return(100 * (x - c(NA, x[-length(x)])) / c(NA, x[-length(x)]))
-  }
-  return(100 * (y - x) / x)
-}
-
-# It's fairly common to need to grab the last N [whatever] of values.
-# The problem with using tail() for this comes in the case where (perhaps
-# due to backfilling) the last rows are not actually the last rows. This
-# function will provide a 'safe' tail mechanism.
-safe_tail <- function(x, n, silent = TRUE) {
-  if (!is.vector(x) && !is.data.frame(x)) {
-    stop("safe_trail() only works with vectors and data frames.")
-  }
-  # \code{silent} suppresses messages which may be used for debugging
-  if (is.vector(x)) {
-    return(tail(sort(x), n))
-  }
-  # Intelligently figure out which column is the date/timestamp column (in 
case it's not the first column):
-  timestamp_column <- names(x)[sapply(x, class) %in% c("Date", "POSIXt", 
"POSIXlt", "POSIXct")]
-  if (length(timestamp_column) == 0) {
-    if (!silent) {
-      message("No date/timestamp column detected for this dataset. It'd be 
faster to use tail().")
-    }
-    return(tail(x, n))
-  }
-  if (length(timestamp_column) > 1) warning("More than one date/timestamp 
column detected. Defaulting to the first one.")
-  if (!silent) {
-    message("Sorting by the date/timestamp column before returning the bottom 
", n, " rows.")
-  }
-  return(tail(x[order(x[[timestamp_column[1]]]), ], n))
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/239858
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I421532aac2c43b077a2afae476358ade3a73f551
Gerrit-PatchSet: 1
Gerrit-Project: wikimedia/discovery/rainbow
Gerrit-Branch: master
Gerrit-Owner: OliverKeyes <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to