OliverKeyes has submitted this change and it was merged.

Change subject: Added smoothing and time frame selection + Added Changelog, 
Readme, and Code of Conduct
......................................................................


Added smoothing and time frame selection
+ Added Changelog, Readme, and Code of Conduct

Bug: T118214

Change-Id: I662be4516693430264d4ad1acd91283053bd5ab6
---
A CHANGELOG.md
A CONDUCT.md
A README.md
D functions.R
M server.R
M ui.R
A utils.R
7 files changed, 149 insertions(+), 58 deletions(-)

Approvals:
  OliverKeyes: Verified; Looks good to me, approved



diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..a8fef92
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,9 @@
+# Change Log (Patch Notes)
+All notable changes to this project will be documented in this file.
+
+## 2015/11/10
+- Refactored large sections of code
+- Added smoothing and time frame selection
+- Added a change log
+- Added a contributor code of conduct
+- Added a readme
diff --git a/CONDUCT.md b/CONDUCT.md
new file mode 100644
index 0000000..65c05c5
--- /dev/null
+++ b/CONDUCT.md
@@ -0,0 +1,22 @@
+# Contributor Code of Conduct
+
+As contributors and maintainers of this project, and in the interest of 
fostering an open and welcoming community, we pledge to respect all people who 
contribute through reporting issues, posting feature requests, updating 
documentation, submitting pull requests or patches, and other activities.
+
+We are committed to making participation in this project a harassment-free 
experience for everyone, regardless of level of experience, gender, gender 
identity and expression, sexual orientation, disability, personal appearance, 
body size, race, ethnicity, age, religion, or nationality.
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery
+* Personal attacks
+* Trolling or insulting/derogatory comments
+* Public or private harassment
+* Publishing other's private information, such as physical or electronic 
addresses, without explicit permission
+* Other unethical or unprofessional conduct.
+
+Project maintainers have the right and responsibility to remove, edit, or 
reject comments, commits, code, wiki edits, issues, and other contributions 
that are not aligned to this Code of Conduct. By adopting this Code of Conduct, 
project maintainers commit themselves to fairly and consistently applying these 
principles to every aspect of managing this project. Project maintainers who do 
not follow or enforce the Code of Conduct may be permanently removed from the 
project team.
+
+This code of conduct applies both within project spaces and in public spaces 
when an individual is representing the project or its community.
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be 
reported by opening an issue or contacting one or more of the project 
maintainers.
+
+This Code of Conduct is adapted from the [Contributor 
Covenant](http://contributor-covenant.org), version 1.2.0, available at 
[http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..07d9ccd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,22 @@
+# External Referrals Dashboard
+
+This project is part of the [Discovery 
Dashboards](http://discovery.wmflabs.org/) project.
+
+## Quick start
+
+Install the dependencies:
+
+```
+$ R
+R> install.packages(c('reshape2', 'devtools', 'data.table'))
+R> 
devtools::install_git('https://gerrit.wikimedia.org/r/wikimedia/discovery/polloi')
+```
+
+Run the server:
+
+```
+$ R
+R> shiny::runApp(launch.browser = 0)
+```
+
+Please note that this project is released with a [Contributor Code of 
Conduct](CONDUCT.md). By participating in this project you agree to abide by 
its terms.
diff --git a/functions.R b/functions.R
deleted file mode 100644
index 08f410d..0000000
--- a/functions.R
+++ /dev/null
@@ -1,42 +0,0 @@
-library(polloi)
-library(data.table)
-
-# Custom function to allow for the selection betwene
-platform_select <- function(name){
-  return(selectizeInput(inputId = name, label = "Platform",
-                        choices = c("All","Desktop","Mobile Web")))
-}
-
-# Read in the traffic data
-read_traffic <- function(){
-  
-  # Read in the initial data and format.
-  data <- as.data.table(polloi::read_dataset(path = 
"external_traffic/referer_data.tsv"))
-  data$is_search <- ifelse(data$is_search, "Referred by search", "Not referred 
by search")
-  data$search_engine[data$search_engine == "None"] <- "Not referred by search"
-  # Write out the overall values for traffic
-  holding <- data[,j=list(pageviews = sum(pageviews)), by = c("timestamp", 
"is_search", "access_method")]
-  holding <- split(holding, f = holding$access_method)
-  holding$all <- data[,j=list(pageviews = sum(pageviews)), by = c("timestamp", 
"is_search")]
-  names(holding) <- c("Desktop", "Mobile Web", "All")
-  summary_traffic_data <<- lapply(holding, function(x){
-    return(reshape2::dcast(x, formula = timestamp ~ is_search, fun.aggregate = 
sum))
-  })
-
-  # Generate per-engine values
-  holding <- data[, j = list(pageviews = sum(pageviews)), by = c("timestamp", 
"search_engine", "access_method")]
-  holding <- split(holding, f = holding$access_method)
-  holding$all <- data[,j=list(pageviews = sum(pageviews)), by = c("timestamp", 
"search_engine")]
-  names(holding) <- c("Desktop", "Mobile Web", "All")
-  bysearch_traffic_data <<- lapply(holding, function(x){
-    return(reshape2::dcast(x, formula = timestamp ~ search_engine, 
fun.aggregate = sum))
-  })
-  return(invisible())
-}
-
-logscale <- function(data, logscale_setting){
-  if(logscale_setting){
-    return(cbind(data[,1], as.data.frame(apply(data[,2:ncol(data)], 2, 
log10))))
-  }
-  return(data)
-}
diff --git a/server.R b/server.R
index b16f226..cb17d99 100644
--- a/server.R
+++ b/server.R
@@ -1,4 +1,4 @@
-source("functions.R")
+source("utils.R")
 
 existing_date <- Sys.Date() - 1
 
@@ -9,15 +9,27 @@
     existing_date <<- Sys.Date()
   }
   
+  # Wrap time_frame_range to provide global settings
+  time_frame_range <- function(input_local_timeframe, input_local_daterange) {
+    return(polloi::time_frame_range(input_local_timeframe, 
input_local_daterange, input$timeframe_global, input$daterange_global))
+  }
+  
   output$traffic_summary_dygraph <- renderDygraph({
-    polloi::make_dygraph(
-      data = summary_traffic_data[[input$platform_traffic_summary]],
-      xlab = "Date", ylab = "Pageviews", title = "Pageviews from external 
search engines")
+    summary_traffic_data[[input$platform_traffic_summary]] %>%
+      polloi::smoother(smooth_level = 
polloi::smooth_switch(input$smoothing_global, input$smoothing_traffic_summary)) 
%>%
+      
polloi::subset_by_date_range(time_frame_range(input$traffic_summary_timeframe, 
input$traffic_summary_timeframe_daterange)) %>%
+      polloi::make_dygraph(xlab = "Date", ylab = "Pageviews",
+                           title = "Pageviews from external search engines") 
%>%
+      dyLegend(labelsDiv = "traffic_summary_legend", show = "always")
   })
   
   output$traffic_bysearch_dygraph <- renderDygraph({
-    polloi::make_dygraph(
-      data = 
logscale(bysearch_traffic_data[[input$platform_traffic_bysearch]], 
input$platform_traffic_bysearch_log),
-      xlab = "Date", ylab = "Pageviews", title = "Pageviews from external 
search engines, broken down by engine")
+    bysearch_traffic_data[[input$platform_traffic_bysearch]] %>%
+      logscale(input$platform_traffic_bysearch_log) %>%
+      polloi::smoother(smooth_level = 
polloi::smooth_switch(input$smoothing_global, 
input$smoothing_traffic_bysearch)) %>%
+      
polloi::subset_by_date_range(time_frame_range(input$traffic_bysearch_timeframe, 
input$traffic_bysearch_timeframe_daterange)) %>%
+      polloi::make_dygraph(xlab = "Date", ylab = "Pageviews",
+                           title = "Pageviews from external search engines, 
broken down by engine") %>%
+      dyLegend(labelsDiv = "traffic_bysearch_legend", show = "always")
   })
 })
diff --git a/ui.R b/ui.R
index dc6a1f2..dfdc259 100644
--- a/ui.R
+++ b/ui.R
@@ -1,8 +1,6 @@
 library(shiny)
 library(shinydashboard)
 library(dygraphs)
-options(scipen = 500)
-source("functions.R")
 
 #Header elements for the visualisation
 header <- dashboardHeader(title = "External Search Traffic", disable = FALSE)
@@ -12,25 +10,51 @@
     tags$link(rel = "stylesheet", type = "text/css", href = "stylesheet.css"),
     tags$script(src = "custom.js")
   ),
-  sidebarMenu(menuItem(text = "Traffic"),
-              menuSubItem(text = "Summary", tabName = "traffic_summary"),
-              menuSubItem(text = "Pageviews by search engine", tabName = 
"traffic_by_engine")
+  sidebarMenu(
+    menuItem(text = "Traffic",
+             menuSubItem(text = "Summary", tabName = "traffic_summary"),
+             menuSubItem(text = "Pageviews by search engine", tabName = 
"traffic_by_engine")),
+    menuItem(text = "Global Settings",
+             selectInput(inputId = "smoothing_global", label = "Smoothing", 
selectize = TRUE, selected = "day",
+                         choices = c("No Smoothing" = "day", "Weekly Median" = 
"week", "Monthly Median" = "month")),
+             selectInput(inputId = "timeframe_global", label = "Time Frame", 
selectize = TRUE, selected = "",
+                         choices = c("All available data" = "all", "Last 7 
days" = "week", "Last 30 days" = "month",
+                                     "Last 90 days" = "quarter", "Custom" = 
"custom")),
+             conditionalPanel("input.timeframe_global == 'custom'",
+                              dateRangeInput("daterange_global", label = 
"Custom Date Range",
+                                             start = Sys.Date()-11, end = 
Sys.Date()-1, min = "2015-04-14")),
+             icon = icon("cog", lib = "glyphicon"))
   )
 )
+
+# Custom function to allow for the selection betwene
+platform_select <- function(name){
+  return(selectizeInput(inputId = name, label = "Platform",
+                        choices = c("All","Desktop","Mobile Web")))
+}
 
 body <- dashboardBody(
   tabItems(
     tabItem(tabName = "traffic_summary",
-            platform_select("platform_traffic_summary"),
+            fluidRow(
+              column(platform_select("platform_traffic_summary"), width = 3),
+              column(polloi::smooth_select("smoothing_traffic_summary"), width 
= 3),
+              column(polloi::timeframe_select("traffic_summary_timeframe"), 
width = 3),
+              column(polloi::timeframe_daterange("traffic_summary_timeframe"), 
width = 3)),
             dygraphOutput("traffic_summary_dygraph"),
+            div(id = "traffic_summary_legend", style = "text-align: right;"),
             includeMarkdown("./tab_documentation/traffic_summary.md")
     ),
     tabItem(tabName = "traffic_by_engine",
-            platform_select("platform_traffic_bysearch"),
-            checkboxInput("platform_traffic_bysearch_log", label = "Log 
scale", value = FALSE),
+            fluidRow(
+              column(platform_select("platform_traffic_bysearch"), width = 2),
+              column(checkboxInput("platform_traffic_bysearch_log", label = 
"Log10 Scale", value = FALSE), width = 1),
+              column(polloi::smooth_select("smoothing_traffic_bysearch"), 
width = 3),
+              column(polloi::timeframe_select("traffic_bysearch_timeframe"), 
width = 3),
+              
column(polloi::timeframe_daterange("traffic_bysearch_timeframe"), width = 3)),
             dygraphOutput("traffic_bysearch_dygraph"),
+            div(id = "traffic_bysearch_legend", style = "text-align: right;"),
             includeMarkdown("./tab_documentation/traffic_byengine.md")
-            
     )
   )
 )
diff --git a/utils.R b/utils.R
new file mode 100644
index 0000000..28413b7
--- /dev/null
+++ b/utils.R
@@ -0,0 +1,44 @@
+library(polloi)
+library(data.table)
+
+# Read in the traffic data
+read_traffic <- function() {
+  
+  # Read in the initial data and format.
+  data <- polloi::read_dataset(path = "external_traffic/referer_data.tsv") %>%
+    dplyr::rename(date = timestamp) %>%
+    as.data.table
+  data$is_search <- ifelse(data$is_search, "Referred by search", "Not referred 
by search")
+  data$search_engine[data$search_engine == "None"] <- "Not referred by search"
+  
+  # Write out the overall values for traffic
+  holding <- data[, j = list(pageviews = sum(pageviews)),
+                  by = c("date", "is_search", "access_method")]
+  holding <- split(holding, f = holding$access_method)
+  holding$all <- data[,j = list(pageviews = sum(pageviews)),
+                      by = c("date", "is_search")]
+  names(holding) <- c("Desktop", "Mobile Web", "All")
+  summary_traffic_data <<- lapply(holding, function(x){
+    return(reshape2::dcast(x, formula = date ~ is_search, fun.aggregate = sum))
+  })
+  
+  # Generate per-engine values
+  holding <- data[, j = list(pageviews = sum(pageviews)),
+                  by = c("date", "search_engine", "access_method")]
+  holding <- split(holding, f = holding$access_method)
+  holding$all <- data[, j = list(pageviews = sum(pageviews)),
+                      by = c("date", "search_engine")]
+  names(holding) <- c("Desktop", "Mobile Web", "All")
+  bysearch_traffic_data <<- lapply(holding, function(x){
+    return(reshape2::dcast(x, formula = date ~ search_engine, fun.aggregate = 
sum))
+  })
+  
+  return(invisible())
+}
+
+logscale <- function(data, logscale_setting){
+  if (logscale_setting) {
+    return(cbind(date = data$date, as.data.frame(apply(data[, 2:ncol(data)], 
2, log10))))
+  }
+  return(data)
+}

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I662be4516693430264d4ad1acd91283053bd5ab6
Gerrit-PatchSet: 2
Gerrit-Project: wikimedia/discovery/wonderbolt
Gerrit-Branch: master
Gerrit-Owner: Bearloga <mpo...@wikimedia.org>
Gerrit-Reviewer: OliverKeyes <oke...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to