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