Bearloga has uploaded a new change for review.

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

Change subject: Add languages visited
......................................................................

Add languages visited

Bug: T140816
Change-Id: Ic05f76d9fd2c0c9c18932c59601031750558a337
---
M functions.R
M server.R
A tab_documentation/languages_summary.md
A tab_documentation/languages_visited.md
M ui.R
M www/stylesheet.css
6 files changed, 344 insertions(+), 32 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/wikimedia/discovery/prince 
refs/changes/05/304505/1

diff --git a/functions.R b/functions.R
index f4428c9..b2ce1f4 100644
--- a/functions.R
+++ b/functions.R
@@ -31,6 +31,11 @@
   return(invisible())
 }
 
+read_langs <- function() {
+  data <- as.data.table(read_dataset(path = "portal/language_destination.tsv"))
+  langs_visited <<- as.data.table(dplyr::left_join(data, get_prefixes()[, -2], 
by = "prefix"))
+}
+
 read_dwelltime <- function(){
   dwelltime_data <<- as.data.table(polloi::read_dataset(path = 
"portal/dwell_metrics.tsv"))
 }
@@ -123,6 +128,24 @@
   
 }
 
+fill_out <- function(x, start_date, end_date, fill = 0) {
+  temp <- data.frame(date = seq(start_date, end_date, "day"))
+  y <- dplyr::right_join(x, temp, by = "date")
+  y[is.na(y)] <- fill
+  return(y)
+}
+
+smart_palette <- function(n_colors) {
+  if (n_colors <= 9) {
+    return(RColorBrewer::brewer.pal(max(3, n_colors), "Set1"))
+  }
+  else if (n_colors < 12) {
+    return(RColorBrewer::brewer.pal(n_colors, "Set3"))
+  } else {
+    return(colorspace::rainbow_hcl(n_colors))
+  }
+}
+
 # Fits an exponential model to the data and returns the rate of growth (or 
decay!)
 get_exp_rate <- function(dates, y) {
   time_frame <- range(dates)
diff --git a/server.R b/server.R
index db5a484..6a193d5 100644
--- a/server.R
+++ b/server.R
@@ -10,13 +10,14 @@
 
 shinyServer(function(input, output, session){
   
-  if(Sys.Date() != existing_date) {
+  if (Sys.Date() != existing_date) {
     read_clickthrough()
+    read_langs()
     read_dwelltime()
     read_country()
-               read_useragents()
-               read_pageviews()
-               read_referrals()
+    read_useragents()
+    read_pageviews()
+    read_referrals()
     existing_date <<- Sys.Date()
   }
   
@@ -29,7 +30,8 @@
                            title = "Wikipedia portal clickthrough rate") %>%
       dyCSS(css = "www/inverse.css") %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
-      dyRangeSelector %>%
+      dyLegend(labelsDiv = "clickthrough_rate_legend", show = "always") %>%
+      dyRangeSelector(strokeColor = "white", fillColor = "gray", 
retainDateWindow = TRUE) %>%
       dyEvent(as.Date("2015-12-07"), "A (sampling change)", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-03-10"), "Search Box Deployed", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-05-18"), "Sister Links Updated", labelLoc = 
"bottom", color = "white") %>%
@@ -43,7 +45,7 @@
                            title = "Actions on the Wikipedia Portal") %>%
       dyCSS(css = "www/inverse.css") %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
-      dyLegend(labelsDiv = "action_breakdown_legend", show = "always", width = 
400) %>%
+      dyLegend(labelsDiv = "action_breakdown_legend", show = "always") %>%
       dyRangeSelector(fillColor = "", strokeColor = "", retainDateWindow = 
TRUE) %>%
       dyEvent(as.Date("2015-12-07"), "A (sampling change)", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-03-10"), "Search Box Deployed", labelLoc = 
"bottom", color = "white") %>%
@@ -58,7 +60,7 @@
                            title = "Most Common Section Per Visit") %>%
       dyCSS(css = "www/inverse.css") %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
-      dyLegend(labelsDiv = "most_common_legend", show = "always", width = 400) 
%>%
+      dyLegend(labelsDiv = "most_common_legend", show = "always") %>%
       dyRangeSelector(fillColor = "", strokeColor = "", retainDateWindow = 
TRUE) %>%
       dyEvent(as.Date("2016-05-18"), "Sister Links Updated", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-06-02"), "Detect Language Deployed", labelLoc = 
"bottom", color = "white")
@@ -71,7 +73,7 @@
                            title = "Actions on the first visit to Wikipedia 
Portal") %>%
       dyCSS(css = "www/inverse.css") %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
-      dyLegend(labelsDiv = "first_visit_legend", show = "always", width = 400) 
%>%
+      dyLegend(labelsDiv = "first_visit_legend", show = "always") %>%
       dyRangeSelector(fillColor = "", strokeColor = "", retainDateWindow = 
TRUE) %>%
       dyEvent(as.Date("2016-03-10"), "Search Box Deployed", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-05-18"), "Sister Links Updated", labelLoc = 
"bottom", color = "white") %>%
@@ -84,6 +86,7 @@
       polloi::make_dygraph(xlab = "Date", ylab = "Dwell Time (Seconds)", title 
= "Time spent on the Wikipedia portal") %>%
       dyCSS(css = "www/inverse.css") %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
+      dyLegend(labelsDiv = "dwelltime_legend", show = "always") %>%
       dyRangeSelector(fillColor = "", strokeColor = "", retainDateWindow = 
TRUE) %>%
       dyEvent(as.Date("2015-12-07"), "A (sampling change)", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-03-10"), "Search Box Deployed", labelLoc = 
"bottom", color = "white") %>%
@@ -127,7 +130,7 @@
       dyLegend(labelsDiv = "country_breakdown_legend", show = "always", width 
= 400) %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
       dyCSS(css = "www/inverse.css") %>%
-      dyRangeSelector %>%
+      dyRangeSelector(strokeColor = "white", fillColor = "gray", 
retainDateWindow = TRUE) %>%
       dyEvent(as.Date("2016-03-10"), "Search Box Deployed", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-05-18"), "Sister Links Updated", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-06-02"), "Detect Language Deployed", labelLoc = 
"bottom", color = "white") %>%
@@ -243,10 +246,12 @@
   
   output$pageview_dygraph <- renderDygraph({
     pageview_data %>%
-      # polloi::smoother(smooth_level = 
polloi::smooth_switch(input$smoothing_global, input$smoothing_pageviews)) %>%
+      polloi::smoother(smooth_level = 
polloi::smooth_switch(input$smoothing_global, input$smoothing_pageviews)) %>%
       polloi::make_dygraph(xlab = "Date", ylab = "Pageviews", title = 
"Pageviews to the Wikipedia Portal") %>%
+      dyLegend(labelsDiv = "pageview_legend", show = "always") %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
-      dyRangeSelector %>%
+      dyAxis("y", logscale = input$pageview_logscale) %>%
+      dyRangeSelector(strokeColor = "white", fillColor = "gray", 
retainDateWindow = TRUE) %>%
       dyEvent(as.Date("2016-03-10"), "Search Box Deployed", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-05-01"), "A (search-redirect.php)", labelLoc = 
"bottom", color = "white") %>%
       dyEvent(as.Date("2016-05-18"), "Sister Links Updated", labelLoc = 
"bottom", color = "white") %>%
@@ -261,7 +266,7 @@
       dyCSS(css = "www/inverse.css") %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
       dyAxis("y", valueFormatter = 'function(x) { return x + "%"; }') %>%
-      dyLegend(labelsDiv = "referer_summary_legend", show = "always", width = 
400) %>%
+      dyLegend(labelsDiv = "referer_summary_legend", show = "always") %>%
       dyRangeSelector(fillColor = "", strokeColor = "", retainDateWindow = 
TRUE) %>%
       dyEvent(as.Date("2016-03-07"), "A (UDF switch)", labelLoc = "bottom", 
color = "white") %>%
       dyEvent(as.Date("2016-05-01"), "B (search-redirect.php)", labelLoc = 
"bottom", color = "white")
@@ -275,8 +280,160 @@
       dyCSS(css = "www/inverse.css") %>%
       dyAxis("x", axisLabelFormatter = polloi::custom_axis_formatter, 
axisLabelWidth = 70) %>%
       dyAxis("y", valueFormatter = 'function(x) { return x + "%"; }') %>%
-      dyLegend(labelsDiv = "search_engines_legend", show = "always", width = 
400) %>%
+      dyLegend(labelsDiv = "search_engines_legend", show = "always") %>%
       dyRangeSelector(fillColor = "", strokeColor = "", retainDateWindow = 
TRUE)
   })
   
+  output$s_dygraph <- renderDygraph({
+    
+    if (!input$s_enwiki) {
+      idx <- langs_visited$prefix != "en"
+    } else {
+      idx <- TRUE
+    }
+    
+    if (input$s_response == "clicks") {
+      if (input$s_type == "count") {
+        data4dygraph <- langs_visited[idx,
+                                      list(
+                                        "total clicks" = sum(clicks),
+                                        search = sum(search),
+                                        primary = sum(primary),
+                                        secondary = sum(secondary)
+                                      ),
+                                      by = c("date")]
+      } else { # == "prop"
+        data4dygraph <- langs_visited[idx,
+                                      list(
+                                        search = 
round(100*sum(search)/sum(clicks), 2),
+                                        primary = 
round(100*sum(primary)/sum(clicks), 2),
+                                        secondary = 
round(100*sum(secondary)/sum(clicks), 2)
+                                      ),
+                                      by = c("date")]
+      }
+      dyout <- data4dygraph %>%
+        fill_out(start_date = min(langs_visited$date), end_date = 
max(langs_visited$date)) %>%
+        polloi::smoother(smooth_level = 
polloi::smooth_switch(input$smoothing_global, input$smoothing_summary)) %>%
+        polloi::make_dygraph(xlab = "Date",
+                             ylab = ifelse(input$s_type == "prop", "Proportion 
of total clicks (%)", "Clicks"),
+                             title = paste("Clicks to Wikipedias ", 
ifelse(input$s_enwiki, "(All Languages)", "(All Except English)"), " from 
Wikipedia.org")) %>%
+        dyRangeSelector(
+          fillColor = ifelse(input$s_type == "prop", "", "gray"),
+          strokeColor = ifelse(input$s_type == "prop", "", "white"),
+          retainDateWindow = TRUE)
+    } else { # == "users"
+      dyout <- langs_visited[, list(users = sum(sessions)), by = "date"] %>%
+        fill_out(start_date = min(langs_visited$date), end_date = 
max(langs_visited$date)) %>%
+        polloi::smoother(smooth_level = 
polloi::smooth_switch(input$smoothing_global, input$smoothing_summary)) %>%
+        polloi::make_dygraph(xlab = "Date", ylab = "Unique sessions", title = 
"Number of users who visited a Wikipedia from Portal") %>%
+        dyRangeSelector(fillColor = "gray", strokeColor = "white", 
retainDateWindow = TRUE)
+    }
+    dyout %>%
+      dyOptions(strokeWidth = 3, labelsKMB = TRUE, drawPoints = FALSE, 
pointSize = 3, includeZero = TRUE,
+                logscale = input$s_response == "clicks" && input$s_type == 
"count" && input$s_logscale) %>%
+      dyLegend(width = 400, labelsDiv = "s_legend", show = "always") %>%
+      dyCSS(css = system.file("custom.css", package = "polloi")) %>%
+      dyEvent(as.Date("2016-03-10"), "Search Box Deployed", labelLoc = 
"bottom", color = "white") %>%
+      dyEvent(as.Date("2016-05-18"), "Sister Links Updated", labelLoc = 
"bottom", color = "white") %>%
+      dyEvent(as.Date("2016-06-02"), "Detect Language Deployed", labelLoc = 
"bottom", color = "white")
+  })
+  
+  lv_reactive <- reactiveValues(choices = NULL, selected_langs = NULL)
+  
+  observeEvent(input$lv_selectall, {
+    lv_reactive$selected_langs <- lv_reactive$choices
+  })
+  
+  observeEvent(input$lv_sort, {
+    if (input$lv_sort %in% c("alphabet_az", "alphabet_za")) {
+      lv_reactive$choices <- sort(unique(langs_visited$language), decreasing = 
input$lv_sort == "alphabet_za")
+    } else {
+      languages <- langs_visited[, list(
+        clicks = sum(clicks),
+        users = sum(sessions),
+        avg_daily_clicks = as.integer(median(clicks)),
+        avg_daily_users = as.integer(median(sessions))),
+        by = "language"]
+      lv_reactive$choices <- switch(input$lv_sort,
+                                    clicks_high2low = {
+                                      
languages$language[order(languages[[input$lv_response]], decreasing = TRUE)]
+                                    },
+                                    clicks_low2high = {
+                                      
languages$language[order(languages[[input$lv_response]], decreasing = FALSE)]
+                                    },
+                                    avg_clicks_high2low = {
+                                      
languages$language[order(languages[[ifelse(input$lv_response == "clicks", 
"avg_daily_clicks", "avg_daily_users")]], decreasing = TRUE)]
+                                    },
+                                    avg_clicks_low2high = {
+                                      
languages$language[order(languages[[ifelse(input$lv_response == "clicks", 
"avg_daily_clicks", "avg_daily_users")]], decreasing = FALSE)]
+                                    },
+                                    top10 = {
+                                      
sort(languages$language[languages[[input$lv_response]] %in% 
head(sort(languages[[input$lv_response]], decreasing = TRUE), 10)], decreasing 
= FALSE)
+                                    },
+                                    bottom50 = {
+                                      
sort(languages$language[languages[[input$lv_response]] %in% 
head(sort(languages[[input$lv_response]], decreasing = FALSE), 50)], decreasing 
= FALSE)
+                                    })
+    }
+    if (!is.null(input$lv_languages)) {
+      if (sum(input$lv_languages %in% lv_reactive$choices) == 0) {
+        lv_reactive$selected_langs <- lv_reactive$choices[1]
+      } else {
+        # Lets us keep selected languages when switching betweeen clicks and 
users
+        lv_reactive$selected_langs <- intersect(input$lv_languages, 
lv_reactive$choices)
+      }
+    }
+    if (is.null(input$lv_languages)) {
+      lv_reactive$selected_langs <- lv_reactive$choices[1]
+    }
+  })
+  
+  output$lv_languages_container <- renderUI({
+    selectInput("lv_languages", label = "Wikipedia languages", 
lv_reactive$choices, lv_reactive$selected_langs, multiple = TRUE)
+  })
+  
+  output$lv_dygraph <- renderDygraph({
+    if (input$lv_response == "clicks") {
+      if (length(input$lv_languages) > 1) {
+        data4dygraph <- langs_visited[langs_visited$language %in% 
input$lv_languages, c("date", "language", "clicks"), with = FALSE] %>%
+          tidyr::spread(language, clicks, fill = 0) %>%
+          fill_out(start_date = min(langs_visited$date), end_date = 
max(langs_visited$date))
+      } else {
+        if (input$lv_type == "count") {
+          data4dygraph <- langs_visited[langs_visited$language == 
input$lv_languages, c("date", "clicks", "search", "primary", "secondary"), with 
= FALSE] %>%
+            fill_out(start_date = min(langs_visited$date), end_date = 
max(langs_visited$date))
+        } else { # == "prop"
+          data4dygraph <- langs_visited[langs_visited$language == 
input$lv_languages, c("date", "clicks", "search", "primary", "secondary"), with 
= FALSE] %>%
+            fill_out(start_date = min(langs_visited$date), end_date = 
max(langs_visited$date))
+          data4dygraph$search <- 
round(100*data4dygraph$search/data4dygraph$clicks, 2)
+          data4dygraph$primary <- 
round(100*data4dygraph$primary/data4dygraph$clicks, 2)
+          data4dygraph$secondary <- 
round(100*data4dygraph$secondary/data4dygraph$clicks, 2)
+          data4dygraph$clicks <- NULL
+        }
+      }
+    } else { # == "users"
+      data4dygraph <- langs_visited[langs_visited$language %in% 
input$lv_languages, c("date", "language", "sessions"), with = FALSE] %>%
+        tidyr::spread(language, sessions, fill = 0) %>%
+        fill_out(start_date = min(langs_visited$date), end_date = 
max(langs_visited$date))
+    }
+    data4dygraph %>%
+    {
+      tryCatch(polloi::smoother(., smooth_level = 
polloi::smooth_switch(input$smoothing_global, input$smoothing_lv)),
+               error = function(e) {
+                 stop("Cannot apply spline smoothing on one or more of the 
selected languages.")
+               }, finally = NULL)
+    } %>%
+      polloi::make_dygraph(xlab = "Date", ylab = ifelse(input$lv_response == 
"clicks", ifelse(input$lv_type == "count", "Clicks", "Proportion of total 
clicks (%)"), "Unique sessions"),
+                           title = paste0(ifelse(input$lv_response == 
"clicks", "Clicks", "Users who went"), " to ", paste0(input$lv_languages, 
collapse = ", ")," Wikipedia", ifelse(length(input$lv_languages) > 1, "s", ""), 
" from Portal")) %>%
+      dyRangeSelector(fillColor = ifelse(input$lv_type == "prop", "", "gray"),
+                      strokeColor = ifelse(input$lv_type == "prop", "", 
"white"),
+                      retainDateWindow = TRUE) %>%
+      dyOptions(strokeWidth = 3, labelsKMB = TRUE, drawPoints = FALSE, 
pointSize = 3, includeZero = TRUE,
+                logscale = input$lv_logscale && input$lv_type == "count") %>%
+      dyLegend(width = 400, labelsDiv = "lv_legend", show = "always") %>%
+      dyCSS(css = system.file("custom.css", package = "polloi")) %>%
+      dyEvent(as.Date("2016-03-10"), "Search Box Deployed", labelLoc = 
"bottom", color = "white") %>%
+      dyEvent(as.Date("2016-05-18"), "Sister Links Updated", labelLoc = 
"bottom", color = "white") %>%
+      dyEvent(as.Date("2016-06-02"), "Detect Language Deployed", labelLoc = 
"bottom", color = "white")
+  })
+  
 })
diff --git a/tab_documentation/languages_summary.md 
b/tab_documentation/languages_summary.md
new file mode 100644
index 0000000..fd2abde
--- /dev/null
+++ b/tab_documentation/languages_summary.md
@@ -0,0 +1,24 @@
+# Traffic to Wikipedia from Wikipedia.org Portal
+
+This dashboard shows the number of clicks (and users) to Wikipedia (across all 
the languages it is in) as recorded by our [Portal event 
logging](https://meta.wikimedia.org/wiki/Schema:WikipediaPortal), which users 
are randomly selected into at a sampling rate of 1 in 200 -- 0.5%. When the 
user comes to wikipedia.org and are randomly selected to be anonymously tracked 
via event logging, we set a timer of 15 minutes. Every time the user comes back 
to the page (lands), the timer is reset. After 15 minutes of not returning, the 
user's session is no longer tracked. For this reason, a single session may have 
one or dozens (sometimes hundreds!) of visits, each with a click or multiple 
clicks. We have seen sessions with as many as hundred clicks following the 
first and only landing. In cases where almost every session only has a single 
click associated with it, the graphs for *clicks* and *users* will look VERY 
similar, if not exactly the same.
+
+When looking at clicks, you can view counts or proportions to see how much of 
the traffic comes from the three sections:
+
+- **search**: wikipedia.org visitors can search Wikipedias in different 
languages and end up on specific articles, in which case we know the language 
of the Wikipedia they visited. If they did not find a specific article, they 
are taken to all a search results page, in which case we will not know the 
language of the Wikipedia they visited.
+- **primary**: the links around the Wikipedia globe logo, which are 
dynamically placed and sorted according to each visitor's language preferences.
+- **secondary**: the links below the Wikipedia globe logo, which the 
wikipedia.org visitor can use to find a version of Wikipedia in any of the 
almost 300 languages.
+
+Until 27 June 2016, traffic to Wikipedias was almost evenly split between 
people searching and people using the primary links. Since then, search has 
been the more dominant section. However, this is due to a rise in Portal 
visitors searching EnWiki from the Portal. If we exclude EnWiki from the total, 
we see that clicks on primary links consistently account for 50-60% of the 
traffic to Wikipedias in languages other than English, searches account for 
~35% of the traffic, and clicks on secondary links account for ~8% of the 
traffic.
+
+## Questions, bug reports, and feature suggestions
+
+For technical, non-bug questions, [email 
Mikhail](mailto:[email protected]?subject=Dashboard%20Question). If you 
experience a bug or notice something wrong or have a suggestion, [open a ticket 
in 
Phabricator](https://phabricator.wikimedia.org/maniphest/task/create/?projects=Discovery)
 in the Discovery board or [email 
Deb](mailto:[email protected]?subject=Dashboard%20Question).
+
+<hr style="border-color: gray;">
+<p style="font-size: small; color: gray;">
+  An experimental dashboard for looking at patterns of <a href= 
"https://www.mediawiki.org/wiki/Wikipedia.org_Portal";>Wikipedia.org Portal</a> 
usage pertaining to users' languages. See <a 
href="https://phabricator.wikimedia.org/T140816";>T140816</a> for more 
information.
+  <strong>Link to this dashboard:</strong>
+  <a href="http://discovery.wmflabs.org/portal/#languages_summary";>
+    http://discovery.wmflabs.org/portal/#languages_summary
+  </a>
+</p>
diff --git a/tab_documentation/languages_visited.md 
b/tab_documentation/languages_visited.md
new file mode 100644
index 0000000..34fe393
--- /dev/null
+++ b/tab_documentation/languages_visited.md
@@ -0,0 +1,27 @@
+# Traffic to Wikipedia in a particular language
+
+This dashboard shows the number of clicks (and users) from Wikipedia.org 
Portal to Wikipedia in any language (that the user may be interested in) as 
recorded by our [Portal event 
logging](https://meta.wikimedia.org/wiki/Schema:WikipediaPortal), which users 
are randomly selected into at a sampling rate of 1 in 200 -- 0.5%. When the 
user comes to wikipedia.org and are randomly selected to be anonymously tracked 
via event logging, we set a timer of 15 minutes. Every time the user comes back 
to the page (lands), the timer is reset. After 15 minutes of not returning, the 
user's session is no longer tracked. For this reason, a single session may have 
one or dozens (sometimes hundreds!) of visits, each with a click or multiple 
clicks. We have seen sessions with as many as hundred clicks following the 
first and only landing. In cases where almost every session only has a single 
click associated with it, the graphs for *clicks* and *users* will look VERY 
similar, if not exactly the same.
+
+While the [summary 
panel](http://discovery-experimental.wmflabs.org/portal/#summary) shows the 
total traffic from the Portal to Wikipedia across all the available languages, 
this panel allows you to view traffic from the Portal to a specific language 
and compare several languages. There are several sorting options to choose 
from, which affects the order of the languages listed when you click to select 
additional languages. Previously selected languages can be removed with the 
backspace key. When switching from one sorting option to another, the selected 
language(s) may change because they might not be part of the new subset of 
languages (e.g. switching from "Top 10" to "Bottom 50"), in which case the 
first language in the list will be selected by default.
+
+When looking at clicks, you can view counts or proportions to see how much of 
the traffic comes from the three sections:
+
+- **search**: wikipedia.org visitors can search Wikipedias in different 
languages and end up on specific articles, in which case we know the language 
of the Wikipedia they visited. If they did not find a specific article, they 
are taken to all a search results page, in which case we will not know the 
language of the Wikipedia they visited.
+- **primary**: the links around the Wikipedia globe logo, which are 
dynamically placed and sorted according to each visitor's language preferences.
+- **secondary**: the links below the Wikipedia globe logo, which the 
wikipedia.org visitor can use to find a version of Wikipedia in any of the 
almost 300 languages.
+
+Viewing count/proportional breakdown of clicks is only available when a single 
language is selected. When multiple languages are selected, only the total 
number of clicks of the three sections is shown for each language.
+
+By far, the English Wikipedia is the most visited one. Majority of the traffic 
to EnWiki is from Portal visitors searching (consistently >50% and as high as 
70%), while *primary link* clicks account for 30-40% of the traffic to EnWiki 
from the Portal.
+
+## Questions, bug reports, and feature suggestions
+
+For technical, non-bug questions, [email 
Mikhail](mailto:[email protected]?subject=Dashboard%20Question). If you 
experience a bug or notice something wrong or have a suggestion, [open a ticket 
in 
Phabricator](https://phabricator.wikimedia.org/maniphest/task/create/?projects=Discovery)
 in the Discovery board or [email 
Deb](mailto:[email protected]?subject=Dashboard%20Question).
+
+<hr style="border-color: gray;">
+<p style="font-size: small; color: gray;">
+  <strong>Link to this dashboard:</strong>
+  <a href="http://discovery.wmflabs.org/portal/#languages_visited";>
+    http://discovery.wmflabs.org/portal/#languages_visited
+  </a>
+</p>
diff --git a/ui.R b/ui.R
index c0c4ba6..a2da850 100644
--- a/ui.R
+++ b/ui.R
@@ -24,6 +24,10 @@
                        menuSubItem(text = "Browser breakdown", tabName = 
"browser_breakdown"),
                        menuSubItem(text = "Pageviews", tabName = 
"pageview_tab"),
                        icon = icon("line-chart")),
+              menuItem("Languages",
+                       menuSubItem(text = "Summary", tabName = 
"languages_summary"),
+                       menuSubItem(text = "Languages visited", tabName = 
"languages_visited"),
+                       icon = icon("globe", lib = "glyphicon")),
               menuItem("External Referrals",
                        menuSubItem(text = "Overall Referral Traffic", tabName 
= "referrals_summary"),
                        menuSubItem(text = "Breakdown by Search Engine", 
tabName = "search_engines"),
@@ -42,33 +46,42 @@
 body <- dashboardBody(
   tabItems(
     tabItem(tabName = "clickthrough_rate",
-            polloi::smooth_select("smoothing_clickthrough_rate"),
+            fluidRow(
+              column(polloi::smooth_select("smoothing_clickthrough_rate"), 
width = 3),
+              column(div(id = "clickthrough_rate_legend", class = "dy-legend 
large"), width = 9)
+            ),
             dygraphOutput("clickthrough_rate_dygraph"),
             includeMarkdown("./tab_documentation/clickthrough_rate.md")
     ),
     tabItem(tabName = "action_breakdown",
-            polloi::smooth_select("smoothing_action_breakdown"),
-            div(dygraphOutput("action_breakdown_dygraph"),
-                div(id = "action_breakdown_legend",
-                    style = "height: 60px; padding-top: 30px; padding-left: 
20px;")),
+            fluidRow(
+              column(polloi::smooth_select("smoothing_action_breakdown"), 
width = 3),
+              column(div(id = "action_breakdown_legend", class = "dy-legend 
large"), width = 9)
+            ),
+            dygraphOutput("action_breakdown_dygraph"),
             includeMarkdown("./tab_documentation/action_breakdown.md")
     ),
     tabItem(tabName = "most_common",
-            polloi::smooth_select("smoothing_most_common"),
-            div(dygraphOutput("most_common_dygraph"),
-                div(id = "most_common_legend",
-                    style = "height: 60px; padding-top: 30px; padding-left: 
20px;")),
+            fluidRow(
+              column(polloi::smooth_select("smoothing_most_common"), width = 
3),
+              column(div(id = "most_common_legend", class = "dy-legend 
large"), width = 9)
+            ),
+            dygraphOutput("most_common_dygraph"),
             includeMarkdown("./tab_documentation/most_common.md")
     ),
     tabItem(tabName = "first_visit",
-            polloi::smooth_select("smoothing_first_visit"),
-            div(dygraphOutput("first_visit_dygraph"),
-                div(id = "first_visit_legend",
-                    style = "height: 60px; padding-top: 30px; padding-left: 
20px;")),
+            fluidRow(
+              column(polloi::smooth_select("smoothing_first_visit"), width = 
3),
+              column(div(id = "first_visit_legend", class = "dy-legend 
large"), width = 9)
+            ),
+            dygraphOutput("first_visit_dygraph"),
             includeMarkdown("./tab_documentation/first_visit.md")
     ),
     tabItem(tabName = "dwell_data",
-            polloi::smooth_select("smoothing_dwelltime"),
+            fluidRow(
+              column(polloi::smooth_select("smoothing_dwelltime"), width = 3),
+              column(div(id = "dwelltime_legend", class = "dy-legend large"), 
width = 9)
+            ),
             dygraphOutput("dwelltime_dygraph"),
             includeMarkdown("./tab_documentation/dwelltime.md")
     ),
@@ -99,30 +112,85 @@
                                                                          
"MediaWiki Support" = "support"))),
                             uiOutput("browser_selector_container"),
                             width = 3),
-                     
column(div(polloi::smooth_select("smoothing_browser_breakdown"),
+                     column(
+                       
div(polloi::smooth_select("smoothing_browser_breakdown"),
                                 dygraphOutput("browser_breakdown_dygraph"),
-                                div(id = "browser_breakdown_legend",
+                                div(id = "browser_breakdown_legend", class = 
"large",
                                     style = "height: 60px; padding-top: 30px; 
padding-left: 20px;"),
                                 style = "width: 100%; background-color: 
#222D32; color: #ECF0F5; padding-top: 10px;"),
                             width = 9)),
             includeMarkdown("./tab_documentation/browsers.md")
     ),
     tabItem(tabName = "pageview_tab",
-            polloi::smooth_select("smoothing_pageviews"),
+            fluidRow(
+              column(polloi::smooth_select("smoothing_pageviews"), width = 3),
+              column(HTML("<label style = \"margin-bottom: 
-10px;\">Scale</label>"),
+                     checkboxInput("pageview_logscale", "Use Log scale", 
FALSE),
+                     width = 4),
+              column(div(id = "pageview_legend", class = "dy-legend large"), 
width = 5)
+            ),
             dygraphOutput("pageview_dygraph"),
             includeMarkdown("./tab_documentation/pageviews.md")
     ),
     tabItem(tabName = "referrals_summary",
             
fluidRow(column(polloi::smooth_select("smoothing_referer_summary"), width = 3),
-                     column(div(id= "referer_summary_legend"), width = 8)),
+                     column(div(id = "referer_summary_legend", class = 
"dy-legend"), width = 9)),
             dygraphOutput("referer_summary_dygraph"),
             includeMarkdown("./tab_documentation/referers_summary.md")
     ),
     tabItem(tabName = "search_engines",
             fluidRow(column(polloi::smooth_select("smoothing_search_engines"), 
width = 3),
-                     column(div(id= "search_engines_legend"), width = 8)),
+                     column(div(id = "search_engines_legend", class = 
"dy-legend large"), width = 9)),
             dygraphOutput("search_engines_dygraph"),
             includeMarkdown("./tab_documentation/referers_byengine.md")
+    ),
+    tabItem(
+      tabName = "languages_summary",
+      fluidRow(
+        column(polloi::smooth_select("smoothing_summary"), width = 3),
+        column(radioButtons("s_response", "Data", list("Clicks" = "clicks", 
"Users" = "users"), inline = TRUE), width = 2),
+        column(HTML("<label class = \"control-label\" style = 
\"margin-bottom:-30px;\">Filter</label>"),
+               checkboxInput("s_enwiki", "Include English Wikipedia", TRUE), 
width = 3),
+        column(conditionalPanel("input.s_response === 'clicks'", 
radioButtons("s_type", "Type", list("Counts" = "count", "Proportions" = 
"prop"), inline = TRUE)), width = 2),
+        column(conditionalPanel("input.s_response === 'clicks' & input.s_type 
=== 'count'",
+                                HTML("<label class = \"control-label\" style = 
\"margin-bottom:-30px;\">Scale</label>"),
+                                checkboxInput("s_logscale", "Use Log scale", 
FALSE)), width = 2)
+      ),
+      dygraphOutput("s_dygraph"),
+      div(id = "s_legend", class = "large", style = "height: 20px; text-align: 
center; padding-top: 10px;"),
+      includeMarkdown("tab_documentation/languages_summary.md")
+    ),
+    tabItem(
+      tabName = "languages_visited",
+      fluidRow(
+        column(polloi::smooth_select("smoothing_lv"), width = 2),
+        column(radioButtons("lv_response", "Data", list("Clicks" = "clicks", 
"Users" = "users"), inline = TRUE), width = 2),
+        column(selectInput("lv_sort", "Sort languages",
+                           list("Alphabetically (A-Z)" = "alphabet_az",
+                                "Alphabetically (Z-A)" = "alphabet_za",
+                                "Overall Clicks (High to Low)" = 
"clicks_high2low",
+                                "Overall Clicks (Low to High)" = 
"clicks_low2high",
+                                "Median Daily Clicks (High to Low)" = 
"avg_clicks_high2low",
+                                "Median Daily Clicks (Low to High)" = 
"avg_clicks_low2high",
+                                "Top 10" = "top10",
+                                "Bottom 50" = "bottom50")),
+               width = 3),
+        column(
+          uiOutput("lv_languages_container", style = "width: 80%; display: 
inline-block; float: left;",
+                   title = "Type to find a language. Use backspace key to 
remove a selected language."),
+                   div(icon("question-circle", class = "fa-lg"),
+                       title = "Type to find a language. Use backspace key to 
remove a selected language.",
+                       style="width: 12.5%; margin-left: 2.5%; padding-top: 
30px; height: 34px; display: inline-block; float: left;"),
+          width = 3),
+        column(
+          conditionalPanel("input.lv_sort === 'top10'", 
actionButton("lv_selectall", "Select all top 10", style = "margin-bottom: 
5px;")),
+          conditionalPanel("input.lv_response === 'clicks' & 
input.lv_languages.length < 2", radioButtons("lv_type", "Type", list("Counts" = 
"count", "Proportions" = "prop"), inline = TRUE)),
+          conditionalPanel("input.lv_type === 'count'", 
checkboxInput("lv_logscale", "Use Log scale", FALSE)),
+          width = 2)
+      ),
+      dygraphOutput("lv_dygraph"),
+      div(id = "lv_legend", class = "large", style = "height: 20px; 
text-align: center; padding-top: 10px;"),
+      includeMarkdown("tab_documentation/languages_visited.md")
     )
   )
 )
diff --git a/www/stylesheet.css b/www/stylesheet.css
index ef814f2..8013eb1 100644
--- a/www/stylesheet.css
+++ b/www/stylesheet.css
@@ -47,3 +47,16 @@
 .sidebar-toggle {
   border-color: black !important;
 }
+
+.dy-legend {
+  text-align: right;
+  padding-top: 15px;
+  padding-bottom: -15px;
+  padding-right: 5%;
+  padding-left: 5%;
+  width: 90%;
+}
+
+.large {
+  font-size: large;
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic05f76d9fd2c0c9c18932c59601031750558a337
Gerrit-PatchSet: 1
Gerrit-Project: wikimedia/discovery/prince
Gerrit-Branch: master
Gerrit-Owner: Bearloga <[email protected]>

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

Reply via email to