GoranSMilovanovic has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/391010 )
Change subject: Init
......................................................................
Init
Change-Id: Ifa894d8effc9cf713bf7b36bd23e46f8e7a7b48c
---
A server.R
A ui.R
A www/Wikidata-logo-en.png
3 files changed, 1,554 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/analytics/wmde/WDCM-Usage-Dashboard
refs/changes/10/391010/1
diff --git a/server.R b/server.R
new file mode 100644
index 0000000..5bdfdd6
--- /dev/null
+++ b/server.R
@@ -0,0 +1,999 @@
+### ---------------------------------------------------------------------------
+### --- WDCM Usage Dashboard, v. Beta 0.1
+### --- Script: server.R, v. Beta 0.1
+### ---------------------------------------------------------------------------
+
+### --- Setup
+rm(list = ls())
+### --------------------------------
+### --- general
+library(shiny)
+library(shinydashboard)
+library(RMySQL)
+library(data.table)
+library(DT)
+library(stringr)
+library(tidyr)
+library(dplyr)
+library(reshape2)
+### --- compute
+library(parallelDist)
+### --- visualization
+library(RColorBrewer)
+library(visNetwork)
+library(networkD3)
+library(ggplot2)
+library(ggrepel)
+library(scales)
+
+### --- Server (Session) Scope
+### --------------------------------
+
+### --- Credentials
+# setwd('/home/goransm/WMDE/WDCM/WDCM_RScripts/WDCM_Dashboard/aux')
+setwd('/srv/shiny-server/aux')
+
+mySQLCreds <- fread("mySQLCreds.csv",
+ header = T,
+ drop = 1)
+
+### -- Connect
+con <- dbConnect(MySQL(),
+ host = "tools.labsdb",
+ defult.file =
"/home/goransm/mySQL_Credentials/replica.my.cnf",
+ dbname = "u16664__wdcm_p",
+ user = mySQLCreds$user,
+ password = mySQLCreds$password)
+
+### --- list existing tables
+q <- "SHOW TABLES;"
+res <- dbSendQuery(con, q)
+st <- fetch(res, -1)
+dbClearResult(res)
+colnames(st) <- "tables"
+
+### --- SET CHARACTER SET utf8
+q <- "SET CHARACTER SET utf8;"
+res <- dbSendQuery(con, q)
+dbClearResult(res)
+
+### --- fetch wdcm2_project
+q <- "SELECT * FROM wdcm2_project;"
+res <- dbSendQuery(con, q)
+wdcmProject <- fetch(res, -1)
+dbClearResult(res)
+colnames(wdcmProject) <- c('Project', 'Usage', 'Project Type')
+
+### --- fetch wdcm2_project_category
+q <- "SELECT * FROM wdcm2_project_category;"
+res <- dbSendQuery(con, q)
+wdcmProjectCategory <- fetch(res, -1)
+dbClearResult(res)
+colnames(wdcmProjectCategory) <- c('Project', 'Category', 'Usage', 'Project
Type')
+
+### --- fetch wdcm2_project_item100
+q <- "SELECT * FROM wdcm2_project_item100;"
+res <- dbSendQuery(con, q)
+wdcmProjectItem100 <- fetch(res, -1)
+dbClearResult(res)
+colnames(wdcmProjectItem100) <- c('Project', 'EntityID', 'Usage', 'Project
Type', 'Label')
+
+### --- fetch wdcm2_project_category_item100
+q <- "SELECT * FROM wdcm2_project_category_item100;"
+res <- dbSendQuery(con, q)
+wdcmProjectCategoryItem100 <- fetch(res, -1)
+dbClearResult(res)
+colnames(wdcmProjectCategoryItem100) <- c('Project', 'Category', 'EntityID',
'Usage', 'Project Type', 'Label')
+
+### --- fetch wdcm2_category
+q <- "SELECT * FROM wdcm2_category;"
+res <- dbSendQuery(con, q)
+wdcmCategory <- fetch(res, -1)
+dbClearResult(res)
+colnames(wdcmCategory) <- c('Category', 'Usage')
+
+### --- fetch wdcm2_category_item100
+q <- "SELECT * FROM wdcm2_category_item100;"
+res <- dbSendQuery(con, q)
+wdcmCategoryItem100 <- fetch(res, -1)
+dbClearResult(res)
+colnames(wdcmCategoryItem100) <- c('EntityID', 'Usage', 'Category', 'Label')
+
+### --- Disconnect
+dbDisconnect(con)
+
+### --- Compute per `Project Type` tables
+# - wdcmProjectType
+wdcmProjectType <- wdcmProject %>%
+ group_by(`Project Type`) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+# - wdcmProjectTypeCategory
+wdcmProjectTypeCategory <- wdcmProjectCategory %>%
+ group_by(`Project Type`, Category) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+# - wdcmProjectTypeItem100
+wdcmProjectTypeItem100 <- wdcmProjectItem100 %>%
+ select(`Project Type`, EntityID, Label, Usage) %>%
+ group_by(`Project Type`, EntityID, Label) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(`Project Type`, desc(Usage))
+
+### --- Compute project similarity structure
+projectSimilarity <- wdcmProjectCategory %>%
+ dplyr::select(Project, Category, Usage) %>%
+ tidyr::spread(key = Category,
+ value = Usage,
+ fill = 0)
+projectNames <- projectSimilarity$Project
+projectSimilarity$Project <- NULL
+# - normalize:
+projectSimilarity <- t(apply(projectSimilarity, 1, function(x) {x/sum(x)}))
+# projectSimilarity[projectSimilarity > 0] <- 1
+projectSimilarity <- as.matrix(parDist(as.matrix(projectSimilarity), method =
"kullback"))
+rownames(projectSimilarity) <- projectNames
+colnames(projectSimilarity) <- projectNames
+
+### - Determine Constants
+# - determine Projects
+projects <- wdcmProject$Project
+# - determine present Project Types
+projectTypes <- unique(wdcmProject$`Project Type`)
+# - and assign Brewer colors
+lengthProjectColor <- length(unique(wdcmProject$`Project Type`))
+projectTypeColor <- brewer.pal(lengthProjectColor, "Set1")
+names(projectTypeColor) <- unique(wdcmProject$`Project Type`)
+# - determine Categories
+categories <- wdcmCategory$Category
+# - totalUsage
+totalUsage <- sum(wdcmProject$Usage)
+totalProjects <- length(wdcmProject$Project)
+totalCategories <- length(wdcmCategory$Category)
+totalProjectTypes <- length(wdcmProjectType$`Project Type`)
+
+### --- prepare search constants for Tabs/Crosstabs
+search_projectTypes <- paste("_", projectTypes, sep = "")
+unzip_projectTypes <- lapply(projectTypes, function(x) {
+ wdcmProject$Project[which(wdcmProject$`Project Type` %in% x)]
+})
+names(unzip_projectTypes) <- search_projectTypes
+
+### --- shinyServer
+shinyServer(function(input, output, session) {
+
+ ### ----------------------------------
+ ### --- BASIC FACTS
+ ### ----------------------------------
+
+ ### --- valueBox: totalUsage
+ # output$totalUsageBox
+ output$totalUsageBox <- renderValueBox({
+ valueBox(
+ value = as.character(totalUsage),
+ subtitle = "Total Wikidata Item Usage",
+ icon = icon("bars", lib = "font-awesome"),
+ color = "blue"
+ )
+ }) # END output$totalUsageBox
+
+ ### --- valueBox: totalProjects
+ # output$totalProjectsBox
+ output$totalProjectsBox <- renderValueBox({
+ valueBox(
+ value = as.character(totalProjects),
+ subtitle = "Projects Tracked",
+ icon = icon("bars", lib = "font-awesome"),
+ color = "blue"
+ )
+ }) # END output$totalProjectsBox
+
+ ### --- valueBox: totalCategories
+ # output$totalCategoriesBox
+ output$totalCategoriesBox <- renderValueBox({
+ valueBox(
+ value = as.character(totalCategories),
+ subtitle = "Semantic Categories",
+ icon = icon("bars", lib = "font-awesome"),
+ color = "blue"
+ )
+ }) # END output$totalCategoriesBox
+
+ ### --- valueBox: totalProjectTypes
+ # output$totalProjectTypesBox
+ output$totalProjectTypesBox <- renderValueBox({
+ valueBox(
+ value = as.character(totalProjectTypes),
+ subtitle = "Project Types",
+ icon = icon("bars", lib = "font-awesome"),
+ color = "blue"
+ )
+ }) # END output$totalProjectTypesBox
+
+ ### ----------------------------------
+ ### --- CATEGORIES OVERVIEW
+ ### ----------------------------------
+
+ ### --- SELECT: update select 'categories'
+ updateSelectizeInput(session,
+ 'categories',
+ choices = categories,
+ selected = categories[round(runif(1, 1,
length(categories)))],
+ server = TRUE)
+
+ ### --- htmlOutput: categoryProjects_overview_Title
+ output$categoryProjects_overview_Title <- renderText({
+ paste("<b>", input$categories, " top 30 projects:</b>")
+ })
+
+ ### --- lineplot: categoryProjects_overview
+ output$categoryProjects_overview <- renderPlot({
+ if (!(input$categories == "")) {
+ plotFrame <- wdcmProjectCategory %>%
+ select(Project, Category, Usage) %>%
+ filter(Category %in% input$categories) %>%
+ arrange(desc(Usage))
+ otherSum <- sum(plotFrame$Usage[31:dim(plotFrame)[1]])
+ other <- data.frame(Project = 'Other',
+ Category = input$categories,
+ Usage = otherSum,
+ stringsAsFactors = F)
+ plotFrame <- rbind(plotFrame[1:30, ], other)
+ plotFrame$Percent <-
paste(round(plotFrame$Usage/sum(plotFrame$Usage)*100, 2),
+ "%", sep = "")
+ plotFrame$Project <- factor(plotFrame$Project,
+ levels =
plotFrame$Project[order(plotFrame$Usage)])
+ ggplot(plotFrame, aes(x = Usage, y = Project)) +
+ geom_line(size = .35, color = "firebrick", group = 1) +
+ geom_point(size = 2, color = "firebrick") +
+ geom_point(size = 1.5, color = "white") +
+ geom_text_repel(aes(label = plotFrame$Percent),
+ size = 3) +
+ xlab("Item Usage") + ylab("Project") +
+ scale_x_continuous(labels = comma) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 0, size = 9, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ } else {
+ return(NULL)
+ }
+ })
+
+ ### --- htmlOutput: categoryItems_overview_Title
+ output$categoryItems_overview_Title <- renderText({
+ paste("<b>", input$categories, " top 30 Wikidata items:</b>")
+ })
+
+ ### --- lineplot: categoryItems_overview
+ output$categoryItems_overview <- renderPlot({
+ if (!(input$categories == "")) {
+ plotFrame <- wdcmCategoryItem100 %>%
+ filter(Category %in% input$categories) %>%
+ arrange(desc(Usage))
+ plotFrame <- plotFrame[1:30, ]
+ plotFrame$Label <- factor(plotFrame$Label,
+ levels =
plotFrame$Label[order(plotFrame$Usage)])
+ ggplot(plotFrame, aes(x = Usage, y = Label)) +
+ geom_line(size = .35, color = "firebrick", group = 1) +
+ geom_point(size = 2, color = "firebrick") +
+ geom_point(size = 1.5, color = "white") +
+ geom_text_repel(aes(label = plotFrame$EntityID),
+ size = 3) +
+ xlab("Item Usage") + ylab("Item") +
+ scale_x_continuous(labels = comma) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 0, size = 9, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ } else {
+ return(NULL)
+ }
+ })
+
+ ### --- lineplot: basicFacts_CategoryLine
+ output$basicFacts_CategoryLine <- renderPlot({
+ plotFrame <- wdcmCategory
+ plotFrame$Percent <- paste(round(plotFrame$Usage/sum(plotFrame$Usage)*100,
2),
+ "%", sep = "")
+ plotFrame$Category <- factor(plotFrame$Category,
+ levels =
plotFrame$Category[order(plotFrame$Usage)])
+ ggplot(plotFrame, aes(x = Usage, y = Category)) +
+ geom_line(size = .35, color = "firebrick", group = 1) +
+ geom_point(size = 2, color = "firebrick") +
+ geom_point(size = 1.5, color = "white") +
+ geom_text_repel(aes(label = plotFrame$Percent),
+ size = 3) +
+ xlab("Item Usage") + ylab("Category") +
+ scale_x_continuous(labels = comma) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 0, size = 9, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+
+ ### --- barplot: basicFacts_ProjectTypeCategory
+ output$basicFacts_ProjectTypeCategory <- renderPlot({
+ ggplot(wdcmProjectTypeCategory, aes(y = log(Usage), x = Category, color =
Category, fill = Category)) +
+ geom_bar(stat = "identity", width = .15) +
+ facet_wrap(~wdcmProjectTypeCategory$`Project Type`, ncol = 3) +
+ xlab("Category") + ylab("log(Item Usage)") +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 90, size = 9, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) +
+ theme(legend.position = "top") +
+ theme(strip.background = element_blank()) +
+ theme(strip.text = element_text(face = "bold")) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+
+ ### ----------------------------------
+ ### --- PROJECT OVERVIEW
+ ### ----------------------------------
+
+ ### --- SELECT: update select 'projects'
+ updateSelectizeInput(session,
+ 'projects',
+ choices = projects,
+ selected = projects[round(runif(1, 1,
length(projects)))],
+ server = TRUE)
+
+ ### --- barplot: projectOverview_Category
+ output$projectOverview_Category <- renderPlot({
+ plotFrame <- wdcmProjectCategory %>%
+ filter(Project %in% input$projects)
+ ggplot(plotFrame, aes(y = Usage, x = Category, color = Category, fill =
Category)) +
+ geom_bar(stat = "identity", width = .15) +
+ xlab("Category") + ylab("Item Usage") +
+ scale_y_continuous(labels = comma) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 90, size = 9, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) +
+ theme(legend.position = "top") +
+ theme(legend.title = element_blank()) +
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+
+ ### --- htmlOutput: projectOverview_Report
+ output$projectOverview_Report <- renderText({
+ # - project:
+ project <- input$projects
+ # - total project rank:
+ totalRank <- which(wdcmProject$Project %in% input$projects)
+ # - total projects:
+ totalProjects <- length(projects)
+ # - usage volume:
+ volume <- wdcmProject$Usage[totalRank]
+ # - percentage of total Wikidata usage:
+ percVolume <- paste(round(volume/sum(wdcmProject$Usage)*100, 2), "%", sep
= "")
+ # - rank in its `Project Type`
+ projectType <- wdcmProject$`Project Type`[totalRank]
+ rankType <- wdcmProject %>%
+ filter(`Project Type` %in% projectType) %>%
+ arrange(desc(Usage))
+ rankProjectType <- which(rankType$Project %in% project)
+ # - total projects of this type
+ totalProjectType <- dim(rankType)[1]
+ paste("<p align = \"right\"><br><br><br><br>Wikidata usage on <b>",
project, "</b>:<br><br>", "<font size = 2><b>", project, "</b> ", " has a total
Wikidata usage volume of <b>",
+ volume, "</b> items (<b>", percVolume, "</b> of total Wikidata usage
across the
+ client projects).<br>In terms of Wikidata usage, it is ranked <b>",
totalRank, "/", totalProjects, "</b> among all client projects, and <b>",
+ rankProjectType, "/", totalProjectType, ".</b> in
+ its Project Type (<b><i>", projectType, "</i></b>).</font></p>", sep
= "") %>%
+ withProgress(message = 'Generating report',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+
+ ### --- htmlOutput: projectOverview_relativeRank_Title
+ output$projectOverview_relativeRank_Title <- renderText({
+ paste("<b>", input$projects, " Wikidata usage rank:</b>")
+ })
+
+ ### --- barplot: projectOverview_relativeRank
+ output$projectOverview_relativeRank <- renderPlot({
+ if (!(input$projects == "")) {
+ ix <- which(wdcmProject$Project %in% input$projects)
+ ixRange <- seq(ix-10, ix+10, by = 1)
+ ixRange <- ixRange[which(ixRange > 0 & ixRange <=
length(wdcmProject$Project))]
+ plotFrame <- wdcmProject[ixRange, ]
+ plotFrame$Rank <- ixRange
+ plotFrame$Color <- rep('cadetblue3', dim(plotFrame)[1])
+ plotFrame$Fill <- rep('white', dim(plotFrame)[1])
+ plotFrame$Fill[which(plotFrame$Project %in% input$projects)] <-
'cadetblue3'
+ plotFrame$Project <- factor(plotFrame$Project,
+ levels =
plotFrame$Project[order(-plotFrame$Usage)])
+ ggplot(plotFrame, aes(y = Usage, x = Project, color = Color, fill =
Fill, label = Rank)) +
+ geom_bar(stat = "identity", width = .1, color = plotFrame$Color, fill
= plotFrame$Fill) +
+ xlab("Project") + ylab("Item Usage") +
+ scale_y_continuous(labels = comma) +
+ geom_label(fill = "cadetblue3",
+ colour = "white",
+ fontface = "bold",
+ position = position_dodge(width = 1),
+ size = 4) +
+ theme_minimal() +
+ theme(legend.position = "none") +
+ theme(axis.text.x = element_text(angle = 90, size = 9, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ } else {
+ return(NULL)
+ }
+ })
+
+ ### --- htmlOutput: projectOverview_semantics_Title
+ output$projectOverview_semantics_Title <- renderText({
+ paste("<b>", input$projects, " Semantic Neighbourhood:</b>")
+ })
+
+ ### --- visNetwork: projectOverview_semantics
+ # - output$projectOverview_semantics
+ output$projectOverview_semantics <- renderVisNetwork({
+
+ if (!(input$projects == "")) {
+ # - select project
+ ix <- which(rownames(projectSimilarity) %in% input$projects)
+ # - select semantic neighbourhood of 15 projects
+ neighbourhood <- c(names(sort(projectSimilarity[ix, -ix], decreasing =
F)[1:20]),
+ rownames(projectSimilarity)[ix])
+ projectsMat <- projectSimilarity[neighbourhood, neighbourhood]
+ # - find most proximal neighbours
+ indexMinDist <- sapply(rownames(projectsMat), function(x) {
+ w <- which(rownames(projectsMat) %in% x)
+ y <- sort(projectsMat[w, -w], decreasing = T)
+ names(y)[length(y)]
+ })
+ id <- 1:length(colnames(projectsMat))
+ label <- colnames(projectsMat)
+ ncolor <- rep("grey", length(colnames(projectsMat)))
+ w <- which(colnames(projectsMat) %in% input$projects)
+ ncolor[w] <- "cadetblue"
+ nodes <- data.frame(id = id,
+ label = label,
+ color = ncolor,
+ stringsAsFactors = F)
+ conceptsStruct <- data.frame(from = names(indexMinDist),
+ to = unname(indexMinDist),
+ stringsAsFactors = F)
+ conceptsStruct$from <- sapply(conceptsStruct$from, function(x) {
+ nodes$id[which(nodes$label %in% x)]
+ })
+ conceptsStruct$to <- sapply(conceptsStruct$to, function(x) {
+ nodes$id[which(nodes$label %in% x)]
+ })
+ conceptsStruct$arrows <- rep("to", length(conceptsStruct$to))
+ visNetwork(nodes = nodes,
+ edges = conceptsStruct,
+ width = "100%",
+ height = "100%") %>%
+ visEvents(type = "once",
+ startStabilizing = "function() {this.moveTo({scale:0.5})}")
%>%
+ visPhysics(stabilization = FALSE) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ } else {
+ return(NULL)
+ }
+ })
+
+ ### --- htmlOutput: projectOverview_topItems_Title
+ output$projectOverview_topItems_Title <- renderText({
+ paste("<b>", input$projects, " top 30 Wikidata items:</b>")
+ })
+
+ ### --- lineplot: projectOverview_topItems
+ output$projectOverview_topItems <- renderPlot({
+ if (!(input$projects == "")) {
+ plotFrame <- wdcmProjectItem100 %>%
+ filter(Project %in% input$projects) %>%
+ arrange(desc(Usage))
+ w <- which(!duplicated(plotFrame$Label))
+ plotFrame <- plotFrame[w, ]
+ plotFrame <- plotFrame[1:30, ]
+ plotFrame$Label <- factor(plotFrame$Label,
+ levels =
plotFrame$Label[order(plotFrame$Usage)])
+ ggplot(plotFrame, aes(x = Usage, y = Label)) +
+ geom_line(size = .35, color = "darkblue", group = 1) +
+ geom_point(size = 2, color = "darkblue") +
+ geom_point(size = 1.5, color = "white") +
+ geom_text_repel(aes(label = plotFrame$EntityID),
+ size = 3) +
+ xlab("Item Usage") + ylab("Item") +
+ scale_x_continuous(labels = comma) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 0, size = 9, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ } else {
+ return(NULL)
+ }
+ })
+
+ ### ----------------------------------
+ ### --- TABS AND CROSSTABS
+ ### ----------------------------------
+
+ ### --- SELECT: update select 'selectProject'
+ updateSelectizeInput(session,
+ 'selectProject',
+ choices = c(projects, paste("_", projectTypes, sep =
"")),
+ selected = c("_Wikipedia", "_Wikinews", "_Wiktionary"),
+ server = TRUE)
+
+ ### --- SELECT: update select 'selectCategories'
+ updateSelectizeInput(session,
+ 'selectCategories',
+ choices = categories,
+ selected = categories[round(runif(6, 1,
length(categories)))],
+ server = TRUE)
+
+ tabsDataset <- reactive({
+ ### --- selected projects:
+ selectedProjects <- character()
+ wUnzip <- which(names(unzip_projectTypes) %in% input$selectProject)
+ if (length(wUnzip > 0)) {
+ selectedProjects <- unname(do.call(c, unzip_projectTypes[wUnzip]))
+ }
+ wSel <- which(projects %in% input$selectProject)
+ if (length(wSel > 0)) {
+ selectedProjects <- c(selectedProjects, projects[wSel])
+ }
+ selectedProjects <- unique(selectedProjects)
+ output$testSelectedProjects <- renderText({
+ paste(selectedProjects, collapse = ", ", sep = "")
+ })
+ ### --- selected categories:
+ selectedCategories <- input$selectCategories
+ ### --- output
+ out <- wdcmProjectCategory %>%
+ filter(Project %in% selectedProjects & Category %in% selectedCategories)
+ out
+ })
+
+ ### --- OBSERVE: input$applySelection
+ observeEvent(input$applySelection, {
+
+ #### --- Chart: tabulations_projectsChart
+ output$tabulations_projectsChart <- renderPlot({
+ # - Chart Frame for output$tabulations_projectsChart
+ plotFrame <- isolate(tabsDataset()) %>%
+ group_by(Project) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ # - top 25 projects:
+ if (dim(plotFrame)[1] >= 25) {
+ plotFrame <- plotFrame[1:25, ]
+ }
+ plotFrame$Project <- factor(plotFrame$Project,
+ levels =
plotFrame$Project[order(-plotFrame$Usage)])
+ # - express labels as K, M:
+ plotFrame$Label <- sapply(plotFrame$Usage, function(x) {
+ if (x >= 1e+03 & x < 1e+06) {
+ out <- paste(round(x/1e+03, 1), "K", sep = "")
+ } else if (x > 1e+06) {
+ out <- paste(round(x/1e+06, 1), "M", sep = "")
+ } else {
+ out <- as.character(x)
+ }
+ return(out)
+ })
+ # - Plot
+ ggplot(plotFrame,
+ aes(x = Project, y = Usage, label = Label)) +
+ geom_bar(stat = "identity", width = .6, fill = "#4c8cff") +
+ xlab('Projects') + ylab('Entity Usage') +
+ ylim(0, max(plotFrame$Usage) + .1*max(plotFrame$Usage)) +
+ scale_y_continuous(labels = comma) +
+ geom_label(size = 3, vjust = -.1) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 90, size = 12, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) +
+ theme(plot.title = element_text(size = 15)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+ # - Download Frame: tabulations_projectsChart
+ tabulations_projectsDownload_Frame <- reactive({
+ plotFrame <- isolate(tabsDataset()) %>%
+ group_by(Project) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ plotFrame
+ })
+ # - Download: tabulations_projectsChart
+ output$tabulations_projectsDownload_Frame <- downloadHandler(
+ filename = function() {
+ 'WDCM_Data.csv'},
+ content = function(file) {
+ write.csv(tabulations_projectsDownload_Frame(),
+ file,
+ quote = FALSE,
+ row.names = FALSE)
+ },
+ contentType = "text/csv"
+ )
+
+ #### --- Chart: tabulations_categoriesChart
+ output$tabulations_categoriesChart <- renderPlot({
+ # - Chart Frame for output$tabulations_categoriesChart
+ plotFrame <- isolate(tabsDataset()) %>%
+ group_by(Category) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ # - top 25 categories:
+ if (dim(plotFrame)[1] > 25) {
+ plotFrame <- plotFrame[1:25, ]
+ }
+ plotFrame$Category <- factor(plotFrame$Category,
+ levels =
plotFrame$Category[order(-plotFrame$Usage)])
+ # - express labels as K, M:
+ plotFrame$Label <- sapply(plotFrame$Usage, function(x) {
+ if (x >= 1e+03 & x < 1e+06) {
+ out <- paste(round(x/1e+03, 1), "K", sep = "")
+ } else if (x > 1e+06) {
+ out <- paste(round(x/1e+06, 1), "M", sep = "")
+ } else {
+ out <- as.character(x)
+ }
+ return(out)
+ })
+ # - Plot
+ ggplot(plotFrame,
+ aes(x = Category, y = Usage, label = Label)) +
+ geom_bar(stat = "identity", width = .6, fill = "#4c8cff") +
+ xlab('Category') + ylab('Entity Usage') +
+ ylim(0, max(plotFrame$Usage) + .1*max(plotFrame$Usage)) +
+ scale_y_continuous(labels = comma) +
+ geom_label(size = 3, vjust = -.1) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 90, size = 12, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) +
+ theme(plot.title = element_text(size = 15)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+ # - Download Frame: tabulations_categoriesChart
+ tabulations_categoriesDownload_Frame <- reactive({
+ plotFrame <- isolate(tabsDataset()) %>%
+ group_by(Category) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ plotFrame
+ })
+ # - Download: tabulations_categoriesChart
+ output$tabulations_categoriesDownload_Frame <- downloadHandler(
+ filename = function() {
+ 'WDCM_Data.csv'},
+ content = function(file) {
+ write.csv(tabulations_categoriesDownload_Frame(),
+ file,
+ quote = FALSE,
+ row.names = FALSE)
+ },
+ contentType = "text/csv"
+ )
+
+ #### --- Chart: tabulations_projectTypesChart
+ output$tabulations_projectTypesChart <- renderPlot({
+ # - Chart Frame for output$tabulations_projectTypesChart
+ plotFrame <- isolate(tabsDataset()) %>%
+ group_by(`Project Type`) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ # - top 25 categories:
+ if (dim(plotFrame)[1] > 25) {
+ plotFrame <- plotFrame[1:25, ]
+ }
+ plotFrame$`Project Type` <- factor(plotFrame$`Project Type`,
+ levels = plotFrame$`Project
Type`[order(-plotFrame$Usage)])
+ # - express labels as K, M:
+ plotFrame$Label <- sapply(plotFrame$Usage, function(x) {
+ if (x >= 1e+03 & x < 1e+06) {
+ out <- paste(round(x/1e+03, 1), "K", sep = "")
+ } else if (x > 1e+06) {
+ out <- paste(round(x/1e+06, 1), "M", sep = "")
+ } else {
+ out <- as.character(x)
+ }
+ return(out)
+ })
+ # - Plot
+ ggplot(plotFrame,
+ aes(x = `Project Type`, y = Usage, label = Label)) +
+ geom_bar(stat = "identity", width = .6, fill = "#4c8cff") +
+ xlab('Project Type') + ylab('Entity Usage') +
+ ylim(0, max(plotFrame$Usage) + .1*max(plotFrame$Usage)) +
+ scale_y_continuous(labels = comma) +
+ geom_label(size = 3, vjust = -.1) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 90, size = 12, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) +
+ theme(plot.title = element_text(size = 15)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+ # - Download Frame: tabulations_projectTypesChart
+ tabulations_projectTypesChartDownload_Frame <- reactive({
+ plotFrame <- isolate(tabsDataset()) %>%
+ group_by(`Project Type`) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ plotFrame
+ })
+ # - Download: tabulations_projectTypesChart
+ output$tabulations_projectTypesChart_Frame <- downloadHandler(
+ filename = function() {
+ 'WDCM_Data.csv'},
+ content = function(file) {
+ write.csv(tabulations_projectTypesChartDownload_Frame(),
+ file,
+ quote = FALSE,
+ row.names = FALSE)
+ },
+ contentType = "text/csv"
+ )
+
+ #### --- Chart: crosstabulations_projectsCategoriesChart
+ output$crosstabulations_projectsCategoriesChart <- renderPlot({
+ # - Chart Frame for output$crosstabulations_projectsCategoriessChart
+ plotFrame <- isolate(tabsDataset()) %>%
+ arrange(desc(Usage))
+ projectOrder <- plotFrame %>%
+ group_by(Project) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ selProj <- projectOrder$Project[1:25]
+ plotFrame <- plotFrame %>%
+ filter(Project %in% selProj)
+ # - express labels as K, M:
+ plotFrame$Label <- sapply(plotFrame$Usage, function(x) {
+ if (x >= 1e+03 & x < 1e+06) {
+ out <- paste(round(x/1e+03, 1), "K", sep = "")
+ } else if (x > 1e+06) {
+ out <- paste(round(x/1e+06, 1), "M", sep = "")
+ } else {
+ out <- as.character(x)
+ }
+ return(out)
+ })
+ plotFrame$Project <- factor(plotFrame$Project,
+ levels = selProj)
+ # - Plot
+ ggplot(plotFrame,
+ aes(x = Project, y = Usage, label = Label)) +
+ geom_line(size = .25, color = "#4c8cff", group = 1) +
+ geom_point(size = 1.5, color = "#4c8cff") +
+ geom_point(size = 1, color = "white") +
+ geom_text_repel(data = plotFrame,
+ aes(x = Project, y = Usage, label = Label),
+ size = 3) +
+ facet_wrap(~ Category, ncol = 3, scales = "free_y") +
+ xlab('Project') + ylab('Entity Usage') +
+ scale_y_continuous(labels = comma) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 90, size = 12, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) +
+ theme(plot.title = element_text(size = 15)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+ # - Download Frame: crosstabulations_projectsCategoriesChart
+ crosstabulations_projectsCategoriesChartDownload_Frame <- reactive({
+ plotFrame <- isolate(tabsDataset()) %>%
+ arrange(desc(Usage))
+ plotFrame
+ })
+ # - Download: crosstabulations_projectsCategoriesFrame
+ output$crosstabulations_projectsCategoriesFrame <- downloadHandler(
+ filename = function() {
+ 'WDCM_Data.csv'},
+ content = function(file) {
+ write.csv(crosstabulations_projectsCategoriesChartDownload_Frame(),
+ file,
+ quote = FALSE,
+ row.names = FALSE)
+ },
+ contentType = "text/csv"
+ )
+
+ #### --- Chart: crosstabulations_projectTypesCategoriesChart
+ output$crosstabulations_projectTypesCategoriesChart <- renderPlot({
+ # - Chart Frame for output$crosstabulations_projectTypesCategoriesChart
+ plotFrame <- isolate(tabsDataset()) %>%
+ group_by(`Project Type`, Category) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ projectTypeOrder <- plotFrame %>%
+ group_by(`Project Type`) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ plotFrame$`Project Type` <- factor(plotFrame$`Project Type`,
+ levels = projectTypeOrder$`Project Type`)
+ # - express labels as K, M:
+ plotFrame$Label <- sapply(plotFrame$Usage, function(x) {
+ if (x >= 1e+03 & x < 1e+06) {
+ out <- paste(round(x/1e+03, 1), "K", sep = "")
+ } else if (x > 1e+06) {
+ out <- paste(round(x/1e+06, 1), "M", sep = "")
+ } else {
+ out <- as.character(x)
+ }
+ return(out)
+ })
+ # - Plot
+ ggplot(plotFrame,
+ aes(x = `Project Type`, y = Usage, label = Label)) +
+ geom_line(size = .25, color = "#4c8cff", group = 1) +
+ geom_point(size = 1.5, color = "#4c8cff") +
+ geom_point(size = 1, color = "white") +
+ geom_text_repel(data = plotFrame,
+ aes(x = `Project Type`, y = Usage, label = Label),
+ size = 3) +
+ facet_wrap(~ Category, ncol = 3, scales = "free_y") +
+ xlab('Project Type') + ylab('Entity Usage') +
+ ylim(0, max(plotFrame$Usage) + .5*max(plotFrame$Usage)) +
+ scale_y_continuous(labels = comma) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 90, size = 12, hjust = 1)) +
+ theme(axis.title.x = element_text(size = 12)) +
+ theme(axis.title.y = element_text(size = 12)) +
+ theme(plot.title = element_text(size = 15)) %>%
+ withProgress(message = 'Generating plot',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 0)})
+ })
+ # - Download Frame: crosstabulations_projectTypeCategoriesChart
+ crosstabulations_projectTypeCategoriesChartDownload_Frame <- reactive({
+ plotFrame <- isolate(tabsDataset()) %>%
+ group_by(`Project Type`, Category) %>%
+ summarise(Usage = sum(Usage)) %>%
+ arrange(desc(Usage))
+ plotFrame
+ })
+ # - Download: crosstabulations_projectTypeCategoriesChartFrame
+ output$crosstabulations_projectTypeCategoriesChartFrame <-
downloadHandler(
+ filename = function() {
+ 'WDCM_Data.csv'},
+ content = function(file) {
+
write.csv(crosstabulations_projectTypeCategoriesChartDownload_Frame(),
+ file,
+ quote = FALSE,
+ row.names = FALSE)
+ },
+ contentType = "text/csv"
+ )
+
+ }, ignoreNULL = FALSE)
+
+
+
+ ### ----------------------------------
+ ### --- TABLES
+ ### ----------------------------------
+
+ ### --- output$projectTable
+ output$projectTable <- DT::renderDataTable({
+ datatable(wdcmProject,
+ options = list(
+ pageLength = 20,
+ width = '100%',
+ columnDefs = list(list(className = 'dt-center', targets =
"_all"))
+ ),
+ rownames = FALSE
+ )
+ }) %>% withProgress(message = 'Generating data',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 1)})
+
+ ### --- output$CategoryTable
+ output$CategoryTable <- DT::renderDataTable({
+ datatable(wdcmCategory,
+ options = list(
+ pageLength = 20,
+ width = '100%',
+ columnDefs = list(list(className = 'dt-center', targets =
"_all"))
+ ),
+ rownames = FALSE
+ )
+ }) %>% withProgress(message = 'Generating data',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 1)})
+
+ ### --- output$projectCategoryDataTable
+ output$projectCategoryDataTable <- DT::renderDataTable({
+ datatable(wdcmProjectCategory,
+ options = list(
+ pageLength = 20,
+ width = '100%',
+ columnDefs = list(list(className = 'dt-center', targets =
"_all"))
+ ),
+ rownames = FALSE
+ )
+ }) %>% withProgress(message = 'Generating data',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 1)})
+
+ ### --- output$projectType
+ output$projectType <- DT::renderDataTable({
+ datatable(wdcmProjectType,
+ options = list(
+ pageLength = 20,
+ width = '100%',
+ columnDefs = list(list(className = 'dt-center', targets =
"_all"))
+ ),
+ rownames = FALSE
+ )
+ }) %>% withProgress(message = 'Generating data',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 1)})
+
+ ### --- output$projectTypeCategory
+ output$projectTypeCategory <- DT::renderDataTable({
+ datatable(wdcmProjectTypeCategory,
+ options = list(
+ pageLength = 20,
+ width = '100%',
+ columnDefs = list(list(className = 'dt-center', targets =
"_all"))
+ ),
+ rownames = FALSE
+ )
+ }) %>% withProgress(message = 'Generating data',
+ min = 0,
+ max = 1,
+ value = 1, {incProgress(amount = 1)})
+
+
+})
+### --- END shinyServer
+
+
+
+
diff --git a/ui.R b/ui.R
new file mode 100644
index 0000000..8a8221b
--- /dev/null
+++ b/ui.R
@@ -0,0 +1,555 @@
+### ---------------------------------------------------------------------------
+### --- WDCM Usage Dashboard, v. Beta 0.1
+### --- Script: ui.R, v. Beta 0.1
+### ---------------------------------------------------------------------------
+
+### --- Setup
+rm(list = ls())
+### --- general
+library(shiny)
+library(shinydashboard)
+library(shinycssloaders)
+### --- outputs
+library(visNetwork)
+library(rbokeh)
+library(networkD3)
+library(DT)
+
+# - options
+options(warn = -1)
+
+shinyUI(
+
+ fluidPage(title = 'WDCM Projects',
+ theme = NULL,
+
+ # - fluidRow Title
+ fluidRow(
+ column(width = 12,
+ h2('WDCM Usage Dashboard'),
+ HTML('<font size="3"><b>Wikidata Concepts
Monitor</b></font>')
+
+ )
+ ), # - fluidRow Title END
+
+ # - fluidRow Logo
+ fluidRow(
+ column(width = 12,
+ img(src='Wikidata-logo-en.png',
+ align = "left")
+ )
+ ), # - fluidRow END
+
+ # - hr()
+ fluidRow(
+ column(width = 12,
+ hr()
+ )
+ ),
+
+ # - fluidRow Boxes
+ fluidRow(
+ column(width = 12,
+ tabBox(id = 'MainBox',
+ selected = 'Dahsboard',
+ title = '',
+ width = 12,
+ height = NULL,
+ side = 'left',
+
+ # - tabPanel Dahsboard
+ tabPanel("Dahsboard",
+ fluidRow(
+ column(width = 12,
+ hr(),
+ tabBox(width = 12,
+ title = '',
+ id = "Usage",
+ selected = "Usage",
+ tabPanel(title = "Usage",
+ id = "usage",
+ fluidRow(
+ column(width = 6,
+ br(),
+ HTML('<font
size=2><b>Note:</b> This page follows a columnar organization: <i>Basic
Facts</i> and <i>Categories</i> to the left, and <i>Projects</i> to the right.
+ The
Dashboard will initialize a random choice of <i>Category</i> and <i>Project</i>
in the <b>Category Report</b> and <b>Project Report</b> areas,
+
respectively. Use the selection and search fields to select a category or a
project that you want to generate a Report
+
for.</font>')
+ )
+ ),
+ # - fluidRow: ValueBoxes
+ fluidRow(
+
+ column(width = 6,
+ fluidRow(
+
column(width = 12,
+
fluidRow(
+
column(width = 12,
+
h3('Basic Facts'),
+
HTML('The total Wikidata item usage, how many sister projects have a
client-side Wikidata usage tracking enabled,
+
how many Wikidata semantic categories of items are encompassed by this
analysis, and how many different
+
Project Types.')
+ )
+ ),
+
fluidRow(
+
column(width = 3,
+
withSpinner(infoBoxOutput("totalUsageBox", width = 12), size = .5)
+
),
+
column(width = 3,
+
withSpinner(valueBoxOutput("totalProjectsBox", width = 12), size = .5)
+
),
+
column(width = 3,
+
withSpinner(valueBoxOutput("totalCategoriesBox", width = 12), size = .5)
+
),
+
column(width = 3,
+
withSpinner(valueBoxOutput("totalProjectTypesBox", width = 12), size = .5)
+
)
+ ),
+
br(), br()
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+ hr(),
+
h3('Category Report'),
+
HTML('Wikidata usage overview for a specific category, including the
distribution of usage in category accross projects
+
and the top Wikidata items per category.'),
+ br(),
br(),
+
selectizeInput('categories',
+
'Select category:',
+
choices = NULL,
+
multiple = FALSE
+ ),
+ br(),
br(),
+
fluidRow(
+
column(width = 12,
+
htmlOutput('categoryProjects_overview_Title'),
+
br(), br(),
+
withSpinner(plotOutput('categoryProjects_overview',
+
width = "700px",
+
height = "450px")
+
)
+ )
+ ),
+
fluidRow(
+
column(width = 12,
+
br(), br(),
+
htmlOutput('categoryItems_overview_Title'),
+
HTML("<font size = 2><b>Note: </b>In the absence of English item label the
Wikidata item ID
+
is used in place of it.</font>"),
+
br(), br(),
+
withSpinner(plotOutput('categoryItems_overview',
+
width = "700px",
+
height = "600px")
+
)
+ )
+ )
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+ hr(),
+
h3('Categories General Overview'),
+
HTML('<b>Wikidata item usage per semantic category</b><br>
+
<font size="2"><b>Note:</b> The current selection of semantic categories does
not
+
encompass all Wikidata items.</font>'),
+ br(),
br(),
+
withSpinner(plotOutput('basicFacts_CategoryLine',
+
width = "700px",
+
height = "500px")
+ )
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+ br(),
br(),
+
HTML('<b>Wikidata item usage per semantic category in each project type</b><br>
+
<font size="2"><b>Note:</b> Item usage count is given on a logarithmic
scale.</font>'),
+ br(),
br(),
+
withSpinner(plotOutput('basicFacts_ProjectTypeCategory',
+
width = "700px",
+
height = "900px")
+
)
+ )
+ )
+ ),
+
+ column(width = 6,
+ fluidRow(
+ column(width
= 12,
+
fluidRow(
+
column(width = 12,
+
h3('Project Report'),
+
HTML('Wikidata usage overview for a specific project, including: the
distribution of usage in Wikidata semantic categories,
+
total Wikidata usage volume, similar projects, and the top Wikidata
items.'),
+
br(), br(),
+
selectizeInput('projects',
+
'Search projects:',
+
choices = NULL,
+
multiple = FALSE
+
),
+
br(), br(),
+
fluidRow(
+
column(width = 4,
+
withSpinner(htmlOutput('projectOverview_Report'))
+
),
+
column(width = 8,
+
withSpinner(plotOutput('projectOverview_Category',
+
width = "550px",
+
height = "450px")
+
)
+
)
+
),
+
fluidRow(
+
column(width = 12,
+
br(), br(),
+
htmlOutput('projectOverview_relativeRank_Title'),
+
br(), br(),
+
withSpinner(plotOutput('projectOverview_relativeRank',
+
width = "800px",
+
height = "350px")
+
)
+
)
+
),
+
fluidRow(
+
column(width = 12,
+
br(), br(),
+
htmlOutput('projectOverview_semantics_Title'),
+
HTML("<font size = 2><b>Note: </b>We study the distribution of
Wikidata usage across the semantic categories to
+
determine which client projects use Wikidata in a similar way.
In this graph, each project points towards the one
+
most similar to it. The selected projects has a different
color. The results are relevant only in the context
+
of the current selection: the selected project + its 20
nearest semantic neighboors.</font>"),
+
withSpinner(visNetwork::visNetworkOutput('projectOverview_semantics',
+
height = 500))
+
)
+
+
),
+
fluidRow(
+
column(width = 12,
+
br(), br(),
+
htmlOutput('projectOverview_topItems_Title'),
+
HTML("<font size = 2><b>Note: </b>In the absence of English item
label the Wikidata item ID
+
is used in place of it.</font>"),
+
br(), br(),
+
withSpinner(plotOutput('projectOverview_topItems',
+
width = "700px",
+
height = "600px")
+
)
+
)
+
)
+
)
+ )
+ )
+ )
+ )
+ )
+
+ ), # - tabPanel
BasicFacts END
+
+ tabPanel(title =
"Tabs/Crosstabs",
+ id = "tabs",
+ fluidRow(
+ column(width = 12,
+ fluidRow(
+ column(width
= 6,
+ br(),
+
HTML('<font size = 2>Here you can make <b>selections</b> of client projects and
semantic categories to learn about Wikidata
+
usage across them.<br> <b>Note:</b> You can search and add projects into the
<i>Search projects</i> field by
+
using (a) <b>project names</b> (e.g. <i>enwiki</i>, <i>dewiki</i>,
<i>sawikiquote</i>, and similar or (b) by using
+
<b>project types</b> that start with <b>"_"</b> (underscore, e.g.
<i>_Wikipedia</i>, <i>_Wikisource</i>, <i>_Commons</i>, and
+
similar; try typing anything into the Select projects field that starts with an
underscore). Please note that by selecting
+
a project type (again: <i>_Wikipedia</i>, <i>_Wikiquote</i>, and similar) you
are selecting <b>all</b> client
+
projects of the respective type, and that\'s potentially a lot of data. The
Dashboard will pick unique
+
projects from whatever you have inserted into the Search projects field. The
selection of projects will be intesected
+
with the selection of semantic categories from the Select categories field, and
the obtained results will refer only
+
to the Wikidata items from the current selection of client projects <i>and</i>
semantic categories.
+
In other words: <i>disjunction</i> operates inside the two search fields, while
<i>conjunction</i> operates
+
across the two search fields.<br> <b>Note:</b> The Dashboard will initialize a
choice of three project types
+
(<i>Wikipedia</i>, <i>Wikinews</i>, and <i>Wiktionary</i>) and a random choice
of six semantic categories. All charts will present at
+
most 25 top projects in respect to the Wikidata usage and relative to the
current selection; however, <b>complete
+
selection data sets</b> are available for download (<i>.csv</i>) beneath each
chart.</font>'),
+ br(),
br()
+ )
+ ),
+ fluidRow(
+ column(width
= 3,
+
selectizeInput('selectProject',
+
'Search projects:',
+
choices = NULL,
+
multiple = TRUE)
+ ),
+ column(width
= 3,
+
selectizeInput('selectCategories',
+
'Search categories:',
+
choices = NULL,
+
multiple = TRUE)
+ )
+ ),
+ fluidRow(
+ column(width
= 2,
+
actionButton('applySelection',
+
label = "Apply Selection",
+
width = '70%',
+
icon = icon("database",
+
class = NULL,
+
lib = "font-awesome")
+
)
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+ hr()
+ )
+ ),
+ fluidRow(
+ column(width
= 6,
+
h4('Projects'),
+
withSpinner(plotOutput('tabulations_projectsChart',
+
height = "600px")),
+
downloadButton('tabulations_projectsDownload_Frame',
+
'Data (csv)')
+ ),
+ column(width
= 6,
+
h4('Categories'),
+
withSpinner(plotOutput('tabulations_categoriesChart',
+
height = "600px")),
+
downloadButton('tabulations_categoriesDownload_Frame',
+
'Data (csv)')
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+ hr()
+ )
+ ),
+ fluidRow(
+ column(width
= 6,
+
h4('Project Types'),
+
withSpinner(plotOutput('tabulations_projectTypesChart',
+
height = "600px")),
+
downloadButton('tabulations_projectTypesChart_Frame',
+
'Data (csv)')
+ ),
+ column(width
= 6
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+ hr()
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+
h4('Project vs Categories'),
+
withSpinner(plotOutput('crosstabulations_projectsCategoriesChart',
+
height = "850px")),
+
downloadButton('crosstabulations_projectsCategoriesFrame',
+
'Data (csv)')
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+ hr()
+ )
+ ),
+ fluidRow(
+ column(width
= 12,
+
h4('Project Types vs Categories'),
+
withSpinner(plotOutput('crosstabulations_projectTypesCategoriesChart',
+
height = "850px")),
+
downloadButton('crosstabulations_projectTypeCategoriesChartFrame',
+
'Data (csv)')
+ )
+ )
+ )
+ ),
+ fluidRow(
+ column(width = 12,
+ hr()
+ )
+ )
+ ), # - tabPanel
Tabs/Crosstabs END
+
+ tabPanel(title = "Tables",
+ id = "tables",
+ fluidRow(
+ column(width = 6,
+ br(),
+ HTML('<font
size = 2>Here you can access <b> some tabulated and cross-tabulated raw
data</b> on Wikidata usage. <br>
+ All
tables can be searched and sorted by any of the respective columns.</font>'),
+ br(), br()
+ )
+ ),
+ fluidRow(
+ column(width = 4,
+ HTML('<font
size = 2><b>Table A. Project Totals.</b></font>'),
+ br(), br(),
+
withSpinner(DT::dataTableOutput('projectTable', width = "100%"))
+ ),
+ column(width = 4,
+ HTML('<font
size = 2><b>Table B. Category Totals.</b></font>'),
+ br(), br(),
+
withSpinner(DT::dataTableOutput('CategoryTable', width = "100%"))
+ ),
+ column(width = 4,
+ HTML('<font
size = 2><b>Table C. Project vs Category Cross-Tabulation.</b></font>'),
+ br(), br(),
+
withSpinner(DT::dataTableOutput('projectCategoryDataTable', width = "100%"))
+ )
+ ),
+ fluidRow(
+ column(width = 12,
+ hr()
+ )
+ ),
+ fluidRow(
+ column(width = 4,
+ HTML('<font
size = 2><b>Table D. Project Type Totals.</b></font>'),
+ br(), br(),
+
withSpinner(DT::dataTableOutput('projectType', width = "100%"))
+ ),
+ column(width = 6,
+ HTML('<font
size = 2><b>Table E. Project Type vs Category Cross-Tabulation.</b></font>'),
+ br(), br(),
+
withSpinner(DT::dataTableOutput('projectTypeCategory', width = "100%"))
+ )
+ )
+ )
+ ) # - tabBox: Wikidata Usage END
+ )
+ )
+
+ ), # - tabPanel Dashboard END
+
+ # - tabPanel Description
+ tabPanel("Description",
+ fluidRow(
+ column(width = 8,
+ HTML('<h2>WDCM Usage
Dashboard</h2>
+
<h4>Description<h4>
+ <hr>
+
<h4>Introduction<h4>
+ <br>
+ <p><font size =
2>This Dashboard is a part of the <b>Wikidata Concepts Monitor (WDMC)</b>. The
WDCM system provides analytics on Wikidata usage
+ across the
Wikimedia sister projects. The WDCM Usage Dashboard focuses on providing the
detailed statistics on Wikidata usage in particular sister projects or
+ the selected
subsets of them. Three pages that present analytical results in this Dashboard
receive a description here: (1) <b><i>Usage</i></b>, (2)
<b><i>Tabs/Crosstabs</i></b>,
+ and (3)
<b><i>Tables</i></b>. But first, definitions.</font></p>
+ <hr>
+
<h4>Definitions</h4>
+ <br>
+ <p><font size =
2><b>N.B.</b> The current <b>Wikidata item usage statistic</b> definition is
<i>the count of the number of pages in a particular client project
+ where the
respective Wikidata item is used</i>. Thus, the current definition ignores the
usage aspects completely. This definition is motivated by the currently
+ present
constraints in Wikidata usage tracking across the client projects
+ (see <a href =
"https://www.mediawiki.org/wiki/Wikibase/Schema/wbc_entity_usage" target =
"_blank">Wikibase/Schema/wbc entity usage</a>).
+ With more mature
Wikidata usage tracking systems, the definition will become a subject
+ of change. The
term <b>Wikidata usage volume</b> is reserved for total Wikidata usage (i.e.
the sum of usage statistics) in a particular
+ client project,
group of client projects, or semantic categories. By a <b>Wikidata semantic
category</b> we mean a selection of Wikidata items that is
+ that is
operationally defined by a respective SPARQL query, returning a selection of
items that intuitivelly match a human, natural semantic category.
+ The structure of
Wikidata does not necessarily match any intuitive human semantics. In WDCM, an
effort is made to select the semantic categories so to match
+ the intuitive,
everyday semantics as much as possible, in order to assist anyone involved in
analytical work with this system. However, the choice of semantic
+ categories in
WDCM is not necessarily exhaustive (i.e. they do not necessarily cover all
Wikidata items), neither the categories are necessarily
+ mutually
exclusive. The Wikidata ontology is very complex and a product of work of many
people, so there is an optimization price to be paid in every attempt to
+ adapt or simplify
its present structure to the needs of a statistical analytical system such as
WDCM. The current set of WDCM semantic categories is thus not
+ normative in any
sense and a subject of change in any moment, depending upon the analytical
needs of the community.</font></p>
+ <p><font size =
2>The currently used <b>WDCM Taxonomy</b> of Wikidata items encompasses the
following 14 semantic categories: <i>Geographical Object</i>,
<i>Organization</i>, <i>Architectural Structure</i>,
+ <i>Human</i>,
<i>Wikimedia</i>, <i>Work of Art</i>, <i>Book</i>, <i>Gene</i>, <i>Scientific
Article</i>, <i>Chemical Entities</i>, <i>Astronomical Object</i>,
<i>Thoroughfare</i>, <i>Event</i>,
+ and
<i>Taxon</i>.</font></p>
+ <hr>
+ <h4>Usage</h4>
+ <br>
+ <p><font size =
2>The Usage tab provides elementary statistics on Wikidata usage across the
semantic categories (left column) and sister projects
+ (right
column).<br>
+ <b><i>To the
left</b></i>, we first encounter a general overview of <i>Basic Facts</i>: the
number of Wikidata items that are encompassed by the current WDCM taxonomy (in
effect,
+ this is the
number of items that are encompassed by all WDCM analyses), the number of
sister projects that have client-side Wikidata usage tracking enabled
(currently,
+ that means that
the <a href = "https://www.mediawiki.org/wiki/Wikibase/Schema/wbc_entity_usage"
target = "_blank">Wikibase/Schema/wbc entity usage</a>) is present there),
+ the number of
semantic categories in the current version of the WDCM Taxonomy, and the number
of different sister project types (e.g. <i>Wikipedia</i>, <i>Wikinews</i>, etc).
+ <br>
+ The <b>Category
Report</b> subsection allows you to select a specific semantic category and
generate two charts beneath the selection: (a) the category top 30 projects
chart, and
+ (b) the category
top 30 Wikidata items chart. The first chart will display 30 sister projects
that use Wikidata items from this semantic category the most, with the usage
data
+ represented on
the horizontal axis, and the project labels on the vertical axis. The
percentages next to the data points in this chart refer to the proportion of
total category usage
+ that takes place
in the respective project. The next chart will display the 30 most popular
items from the selected semantic category: item usage is again placed on the
horizontal axis,
+ item labels are
on the vertical axis, and item IDs are placed next to the data points
themselves.
+ <br>
+ The <b>Categories
General Overview</b> subsection is static and allows no selection; it
introduces two concise overviews of Wikidata usage across the semantic
categories of
+ Wikidata items.
The <i>Wikidata Usage per Semantic Cateory</i> chart provides semantic
categories on the vertical and item usage statistics on the horizontal axis;
the percentages
+ tells us about
the proportion of total Wikidata usage that the respective semantic category
carries. Beneath, the <i>Wikidata item usage per semantic category in each
project type</i>
+ provides a
cross-tabulation of semantic categories vs. sister project types. The
categories are color-coded and represented on the horizontal axes, while each
chart represents one project
+ type. The usage
scale, represented on the vertical axes, is logarithmic to ease the comparison
and enable practical data visualization.
+ <br>
+ <b><i>To the
right</b></i>, an opportunity to inspect Wikidata usage in a single Wikimedia
project is provided. The <b>Project Report</b> section allows you to select a
single Wikimedia
+ project and
obtain results on it. The first section that will be generated upon making a
selection provides a concise narrative summary of Wikidata usage in the
selected project alongside
+ a chart
presenting an overview of Wikidata usage per semantic category. The next chart,
<i>Wikidata usage rank</i>, show the rank position of the selected project
among other sister projects
+ in respect to the
Wikidata usage volume. Beneath, a more complex structure, <i>Semantic
Neighbourhood</i>, is given. In this network, or a directed graph if you
prefere, each project points
+ towards the one
most similar to it. The selected projects has a different color. The results
are relevant only in the context of the current selection: the selected project
and its 20 nearest
+ semantic
neighboors only are presented. Once again: each project points to the one which
utilizes Wikidata in a way most similar to it. The <i>top 30 Wikidata items</i>
chart presents the top 30
+ Wikidata items in
the selected project: item labels are given on the vertical axis, Wikidata
usage on the horizontal axis, and the item IDs are labeled close to the data
points themselves.
+ </font></p>
+ <hr>
+
<h4>Tabs/Crosstabs</h4>
+ <br>
+ <p><font size = 2>
+ Here we have the
most direct opportunity to study the Wikidata usage statistics across the
sister projects. A selection of projects and semantic categories will be
intersected and only results in
+ the scope of the
intersection will be returned. The charts should be self-explanatory: the usage
statistic is always represented by the vertical axis, while the horizontal axis
and sub-panels play
+ various roles in
the context of whether a category vs project or a category vs project type
crosstabulation is provided. Data points are labeled in million (M) or thousand
(K) pages (see Wikidata usage)
+ definition
above). While charts can display a limited number of data points only, relative
to the size of the selection, each of them is accompanied by a <b>Data
(csv)</b> button that will initiate a
+ download of the
full respective data set as a comma separated file.
+ </font></p>
+ <hr>
+ <h4>Tables</h4>
+ <br>
+ <p><font size =
2>The section presents searchable and sortable tables and crosstabulations with
self-explanatory semantics. Access full WDCM usage datasets from
here.</font></p>
+
+ ')
+ )
+ )
+ ), # - tabPanel Usage END
+
+ # - tabPanel Navigate
+ tabPanel("Navigate WDCM",
+ fluidRow(
+ column(width = 8,
+ HTML('<h2>WDCM
Navigate</h2>
+ <h4>Your orientation in the
WDCM Dashboards System<h4>
+ <hr>
+ <ul>
+ <li><b><a href =
"http://wdcm.wmflabs.org/">WDCM Portal</a></b>.<br>
+ <font size = "2">The entry
point to WDCM Dashboards.</font></li><br>
+ <li><b><a href =
"http://wdcm.wmflabs.org/WDCM_OverviewDashboard/">WDCM Overview</a></b><br>
+ <font size = "2">The big
picture. Fundamental insights in how Wikidata is used across the client
projects.</font></li><br>
+ <li><b><a href =
"http://wdcm.wmflabs.org/WDCM_SemanticsDashboard/">WDCM Semantics</a></b><br>
+ <font size = "2">Detailed
insights into the WDCM Taxonomy (a selection of semantic categories from
Wikidata), its distributional
+ semantics, and the way it
is used across the client projects. If you are looking for Topic Models -
that’s where
+ they live.</font></li><br>
+ <li><b><a href =
"http://wdcm.wmflabs.org/WDCM_UsageDashboard/">WDCM Usage</a> (current
dashboard)</b><br>
+ <font size =
"2">Fine-grained information on Wikidata usage across client projects and
project types. Cross-tabulations and similar..</font></li><br>
+ <li><b>WDCM Items</b><br>
+ <font size =
"2">Fine-grained information on particular Wikidata item usage across the
client projects.<b> (Under development)</b></font></li><br>
+ <li><b><a href =
"https://wikitech.wikimedia.org/wiki/Wikidata_Concepts_Monitor">WDCM System
Technical Documentation</a></b><br>
+ <font size = "2">The WDCM
Wikitech Page.</font></li>
+ </ul>'
+ )
+ )
+ )
+ ) # - tabPanel Structure END
+
+ ) # - tabBox END
+
+ ) # - main column of fluidRow Boxes END
+
+ ), # - # - fluidRow Boxes END
+
+ # - fluidRow Footer
+ fluidRow(
+ column(width = 12,
+ hr(),
+ HTML('<b>Wikidata Concepts Monitor :: WMDE
2017</b><br>Diffusion: <a
href="https://phabricator.wikimedia.org/diffusion/AWCM/" target =
"_blank">WDCM</a><br>'),
+ HTML('Contact: Goran S. Milovanovic, Data Scientist,
WMDE<br>e-mail: [email protected]
+ <br>IRC: goransm'),
+ br(),
+ br()
+ )
+ ) # - fluidRow Footer END
+
+ ) # - fluidPage END
+
+) # - ShinyUI END
diff --git a/www/Wikidata-logo-en.png b/www/Wikidata-logo-en.png
new file mode 100644
index 0000000..380ea29
--- /dev/null
+++ b/www/Wikidata-logo-en.png
Binary files differ
--
To view, visit https://gerrit.wikimedia.org/r/391010
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifa894d8effc9cf713bf7b36bd23e46f8e7a7b48c
Gerrit-PatchSet: 1
Gerrit-Project: analytics/wmde/WDCM-Usage-Dashboard
Gerrit-Branch: master
Gerrit-Owner: GoranSMilovanovic <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits