Add shiny-app demo from Meet & Code 2020

Change-Id: I1ba34e7431919b6f717f4bd0398e618c3443f5c9
diff --git a/demo/shiny-apps/frequency_curves/server.R b/demo/shiny-apps/frequency_curves/server.R
new file mode 100644
index 0000000..d1a913d
--- /dev/null
+++ b/demo/shiny-apps/frequency_curves/server.R
@@ -0,0 +1,65 @@
+rsr <- new("KorAPConnection", verbose = TRUE)
+vc <- "referTo ratskorpus & pubDate in"
+years <- c(1995:2019)
+query <- "Aluhut"
+logfile <- file("frequency_curves.log", open = "a")
+
+# override log.info in RKorAPClient to get some progress info
+log.info <- function(v,  ...) {
+  original = paste0(...)
+  detail <- if (str_detect(original, "in ([0-9]{4})")) {
+    str_replace(original, ".*in ([0-9]{4}).*", "Suche in \\1")
+  } else {
+    "Randverteilung"
+  }
+  incProgress(1 / (2 * length(query) * length(years)), detail = detail)
+  cat(original, file = logfile)
+  flush(logfile)
+}
+
+assignInNamespace("log.info", log.info, "RKorAPClient")
+
+plotHighchart <- function(query = c("Tolpatsch", "Tollpatsch"),
+                          vc = "referTo ratskorpus & pubDate in",
+                          years = years,
+                          as.alternatives = F,
+                          conf.level = 0.95,
+                          kco = rsr) {
+  hc <- frequencyQuery(kco,
+                       query,
+                       paste(vc, years),
+                       as.alternatives = as.alternatives) %>%
+    hc_freq_by_year_ci(as.alternatives, smooth = T) %>%
+    hc_add_theme(hc_theme_ids_dark())
+  hc
+}
+
+generateHighchart <- function(wordParam) {
+  if (wordParam != "") {
+    query <<- str_split(wordParam, " *, *", simplify = TRUE)
+    withProgress(message = 'Berechnung läuft: ', value = 0, {
+      hc <- plotHighchart(query, vc , years)
+    })
+    hc
+  }
+}
+
+
+function(input, output, session) {
+  observe({
+    queryParams <- parseQueryString(session$clientData$url_search)
+    if (!is.null(queryParams[['q']])) {
+      paramWord <- queryParams[['q']]
+      updateTextInput(session, "q", value = paramWord)
+      output$hcontainer <-
+        renderHighchart(generateHighchart(paramWord))
+    }
+  })
+  
+  observeEvent(input$goButton,
+               {
+                 output$hcontainer <-
+                   renderHighchart(generateHighchart(isolate(input$q)))
+               })
+  
+}
diff --git a/demo/shiny-apps/frequency_curves/theme-ids-dark.R b/demo/shiny-apps/frequency_curves/theme-ids-dark.R
new file mode 100644
index 0000000..1ff03d2
--- /dev/null
+++ b/demo/shiny-apps/frequency_curves/theme-ids-dark.R
@@ -0,0 +1,228 @@
+#' Dark IDS theme for highcharts
+#'
+#' @param ... Named argument to modify the theme
+#'
+#' @examples
+#'
+#' highcharts_demo() %>%
+#'   hc_add_theme(hc_theme_ids_dark())
+#' @export
+hc_theme_ids_dark <- function(...) {
+  theme <-
+    list(
+      colors = c('#EB7C31', "#1F77B4", "#2CA02C", "#D62728", "#9467BD", "#8C564B", "#E377C2", "#7F7F7F", "#BCBD22", "#17BECF", "#AEC7E8", "#FFBB78", "#98DF8A", "#FF9896", "#C5B0D5", "#C49C94", "#F7B6D2", "#C7C7C7", "#DBDB8D", "#9EDAE5"),
+#      colors = c(
+#        '#EB7C31', "#9BAD0B", "#2b908f", "#90ee7e", "#f45b5b", "#7798BF",
+#        "#aaeeee", "#ff0066", "#eeaaee", "#55BF3B"
+#      ),
+      chart = list(
+        backgroundColor = list(
+          linearGradient = list(x1 = 0, y1 = 1, x2 = 1, y2 = 0),
+          stops = list(
+            list(0, "#2a2a2b"),
+            list(1, "#3e3e3e")
+          )
+        ),
+        style = list(
+          fontFamily = "Roboto Condensed",
+          fontFamily = '"Univers LT Std 47 Cn Lt", "Roboto Condensed", "Unica One", sans-serif-condensed, sans',
+          fontSize = "12pt"
+        ),
+        plotBorderColor = "#606063"
+      ),
+      title = list(
+        style = list(
+          color = "#E0E0E3",
+          fontSize = "20px"
+        )
+      ),
+      subtitle = list(
+        style = list(
+          color = "#E0E0E3",
+          fontSize = "14pt"
+        )
+      ),
+      xAxis = list(
+        gridLineColor = "#707073",
+        labels = list(
+          style = list(
+            color = "#E0E0E3",
+            fontSize = "12pt"
+          )
+        ),
+        lineColor = "#707073",
+        minorGridLineColor = "#505053",
+        tickColor = "#707073",
+        title = list(
+          style = list(
+            color = "#A0A0A3",
+            fontSize = "12pt"
+          )
+        )
+      ),
+      yAxis = list(
+        gridLineColor = "#707073",
+        labels = list(
+          style = list(
+            color = "#E0E0E3",
+            fontSize = "12pt"
+          )
+        ),
+        lineColor = "#707073",
+        minorGridLineColor = "#505053",
+        tickColor = "#707073",
+        tickWidth = 1,
+        title = list(
+          style = list(
+            color = "#A0A0A3",
+            fontSize = "12pt"
+          )
+        )
+      ),
+      tooltip = list(
+        backgroundColor = "rgba(0, 0, 0, 0.85)",
+        style = list(
+          color = "#E0E0E0",
+          fontSize = "11pt"
+        )
+      ),
+      plotOptions = list(
+        series = list(
+          dataLabels = list(
+            color = "#B0B0B3",
+            fontSize = "13pt"
+          ),
+          marker = list(
+            lineColor = "#333"
+          )
+        ),
+        boxplot = list(
+          fillColor = "#505053"
+        ),
+        candlestick = list(
+          lineColor = "white"
+        ),
+        errorbar = list(
+          color = "white"
+        )
+      ),
+      legend = list(
+        itemStyle = list(
+          color = "#E0E0E3"
+        ),
+        itemHoverStyle = list(
+          color = "#FFF"
+        ),
+        itemHiddenStyle = list(
+          color = "#606063"
+        )
+      ),
+      credits = list(
+        style = list(
+          color = "#666"
+        )
+      ),
+      labels = list(
+        style = list(
+          color = "#707073"
+        )
+      ),
+
+      drilldown = list(
+        activeAxisLabelStyle = list(
+          color = "#F0F0F3"
+        ),
+        activeDataLabelStyle = list(
+          color = "#F0F0F3"
+        )
+      ),
+
+      navigation = list(
+        buttonOptions = list(
+          symbolStroke = "#DDDDDD",
+          theme = list(
+            fill = "#505053"
+          )
+        )
+      ),
+
+      rangeSelector = list(
+        buttonTheme = list(
+          fill = "#505053",
+          stroke = "#000000",
+          style = list(
+            color = "#CCC"
+          ),
+          states = list(
+            hover = list(
+              fill = "#707073",
+              stroke = "#000000",
+              style = list(
+                color = "white"
+              )
+            ),
+            select = list(
+              fill = "#000003",
+              stroke = "#000000",
+              style = list(
+                color = "white"
+              )
+            )
+          )
+        ),
+        inputBoxBorderColor = "#505053",
+        inputStyle = list(
+          backgroundColor = "#333",
+          color = "silver"
+        ),
+        labelStyle = list(
+          color = "silver"
+        )
+      ),
+
+      navigator = list(
+        handles = list(
+          backgroundColor = "#666",
+          borderColor = "#AAA"
+        ),
+        outlineColor = "#CCC",
+        maskFill = "rgba(255,255,255,0.1)",
+        series = list(
+          color = "#7798BF",
+          lineColor = "#A6C7ED"
+        ),
+        xAxis = list(
+          gridLineColor = "#505053"
+        )
+      ),
+
+      scrollbar = list(
+        barBackgroundColor = "#808083",
+        barBorderColor = "#808083",
+        buttonArrowColor = "#CCC",
+        buttonBackgroundColor = "#606063",
+        buttonBorderColor = "#606063",
+        rifleColor = "#FFF",
+        trackBackgroundColor = "#404043",
+        trackBorderColor = "#404043"
+      ),
+
+      legendBackgroundColor = "rgba(0, 0, 0, 0)",
+      background2 = "#233238",
+      dataLabelsColor = "#233238",
+      textColor = "#34495e",
+      maskColor = "rgba(255,255,255,0.3)",
+      contrastTextColor = "#F0F0F3"
+    )
+
+  theme <- structure(theme, class = "hc_theme")
+
+  if (length(list(...)) > 0) {
+    theme <- hc_theme_merge(
+      theme,
+      hc_theme(...)
+    )
+  }
+
+  theme
+}
diff --git a/demo/shiny-apps/frequency_curves/ui.R b/demo/shiny-apps/frequency_curves/ui.R
new file mode 100644
index 0000000..f81b83f
--- /dev/null
+++ b/demo/shiny-apps/frequency_curves/ui.R
@@ -0,0 +1,30 @@
+library(shiny)
+library(highcharter)
+library(RKorAPClient)
+library(utils)
+library(stringr)
+source("theme-ids-dark.R")
+
+shinyUI(
+  fluidPage(
+    title = "Wortfrequenzverläufe in DeReKo",
+    tags$link(rel = "stylesheet", type = "text/css", href = "frequency_curves.css"),
+    tags$head(tags$script(src = "enter-button.js")),
+    fluidPage(
+      titlePanel("Wortfrequenzverläufe im Deutschen Referenzkorpus"),
+      fluidRow(
+        height = 2,
+        class = "panel",
+        column(width = 4, textInput("q", label = "Wortform oder Suchausdruck",
+                                    placeholder = "Mit Komma getrennte Liste")),
+        column(
+          width = 1,
+          style = "margin-top: 25px;",
+          actionButton("goButton", "Mit KorAP suchen", icon("search"), class = "btn btn-primary")
+        )
+      ),
+      fluidRow(height = 10,
+               highchartOutput("hcontainer", height = "600px"))
+    )
+  )
+)
diff --git a/demo/shiny-apps/frequency_curves/www/enter-button.js b/demo/shiny-apps/frequency_curves/www/enter-button.js
new file mode 100644
index 0000000..d5138fa
--- /dev/null
+++ b/demo/shiny-apps/frequency_curves/www/enter-button.js
@@ -0,0 +1,5 @@
+$(document).keyup(function(event) {
+    if ($("#q").is(":focus") && (event.key == "Enter")) {
+        $("#goButton").click();
+    }
+});
diff --git a/demo/shiny-apps/frequency_curves/www/frequency_curves.css b/demo/shiny-apps/frequency_curves/www/frequency_curves.css
new file mode 100644
index 0000000..10e2863
--- /dev/null
+++ b/demo/shiny-apps/frequency_curves/www/frequency_curves.css
@@ -0,0 +1,23 @@
+
+.btn-primary {
+  background-color: #9BAD09;
+  border-color: #626F06
+  
+}
+
+.btn-primary:hover {
+  background-color: #626F06
+}
+
+.shiny-notification {
+  position: fixed; 
+  top: 50%;
+  left: 50%;  
+  width: 250px; 
+  margin-top: -100px;
+  margin-left: -125px;
+}
+  
+.progress-bar {
+  background-color: #9BAD09
+} 
\ No newline at end of file