blob: 929ac0a1d5e4beafed52ee80f83ef86ec9c213ab [file] [log] [blame]
Marc Kupietza6e4ee62021-03-05 09:00:15 +01001#' Helper functions for producing highcharts
2#'
3#' @param hc highchart
4#'
5#' @name highcharter-helpers
6NULL
7#' NULL
8
Marc Kupietz91145b02020-01-29 15:58:36 +01009#' Experimental: Plot interactive frequency by year graphs with confidence intervals using highcharter
10#'
11#' Experimental convenience function for plotting typical frequency by year graphs with confidence intervals using highcharter.
12#' \bold{Warning:} This function may be moved to a new package.
13#'
Marc Kupietza6e4ee62021-03-05 09:00:15 +010014#' @rdname highcharter-helpers
Marc Kupietz91145b02020-01-29 15:58:36 +010015#' @import highcharter
Marc Kupietzb7e7f722020-06-02 12:29:18 +020016#' @importFrom tibble add_column
Marc Kupietz91145b02020-01-29 15:58:36 +010017#' @export
18#'
19#' @param df data frame like the value of a \code{\link{frequencyQuery}}
Marc Kupietz43a6ade2020-02-18 17:01:44 +010020#' @param as.alternatives boolean decides whether queries should be treated as mutually exclusive and exhaustive wrt. to some meaningful class (e.g. spelling variants of a certain word form).
Marc Kupietz91145b02020-01-29 15:58:36 +010021#' @param ylabel defaults to \% if \code{as.alternatives} is \code{true} and to "ipm" otherwise.
Marc Kupietzab0b0712020-05-04 16:24:57 +020022#' @param smooth boolean decides whether the graph is smoothed using the highcharts plot types spline and areasplinerange.
Marc Kupietz5b503f42020-04-09 15:26:00 +020023#' @param ... additional arguments passed to \code{\link{hc_add_series}}
Marc Kupietz91145b02020-01-29 15:58:36 +010024#'
25#' @examples
Marc Kupietz657d8e72020-02-25 18:31:50 +010026#' \donttest{year <- c(1990:2018)}\dontshow{year <- c(2013:2013)}
27#' \donttest{alternatives <- c("macht []{0,3} Sinn", "ergibt []{0,3} Sinn")}\dontshow{alternatives <- c("macht []{0,3} Sinn")}
Marc Kupietz91145b02020-01-29 15:58:36 +010028#' new("KorAPConnection", verbose = TRUE) %>%
Marc Kupietz657d8e72020-02-25 18:31:50 +010029#' frequencyQuery(query = alternatives,
Marc Kupietz05b22772020-02-18 21:58:42 +010030#' vc = paste("textType = /Zeit.*/ & pubDate in", year),
Marc Kupietz91145b02020-01-29 15:58:36 +010031#' as.alternatives = TRUE) %>%
32#' hc_freq_by_year_ci(as.alternatives = TRUE)
33#'
Marc Kupietz05b22772020-02-18 21:58:42 +010034#' \donttest{
Marc Kupietz10f65c42020-01-31 15:18:24 +010035#' kco <- new("KorAPConnection", verbose = TRUE)
36#' expand_grid(
37#' condition = c("textDomain = /Wirtschaft.*/", "textDomain != /Wirtschaft.*/"),
38#' year = (2005:2011)
39#' ) %>%
40#' cbind(frequencyQuery(
41#' kco,
42#' "[tt/l=Heuschrecke]",
43#' paste0(.$condition, " & pubDate in ", .$year)
44#' )) %>%
45#' hc_freq_by_year_ci()
Marc Kupietz05b22772020-02-18 21:58:42 +010046#' }
Marc Kupietz10f65c42020-01-31 15:18:24 +010047#'
Marc Kupietzab0b0712020-05-04 16:24:57 +020048hc_freq_by_year_ci <- function(df, as.alternatives = FALSE,
49 ylabel = if(as.alternatives) "%" else "ipm",
50 smooth = FALSE,
51 ...) {
Marc Kupietz91145b02020-01-29 15:58:36 +010052 title <- ""
53 df <- df %>%
54 { if(! as.alternatives) ipm(.) else RKorAPClient::percent(.) }
55
56 if (!"year" %in% colnames(df)) {
Marc Kupietzb7e7f722020-06-02 12:29:18 +020057 df <- df %>% add_column(year = as.integer(queryStringToLabel(df$vc, pubDateOnly = TRUE)))
Marc Kupietz91145b02020-01-29 15:58:36 +010058 }
59 if (!"condition" %in% colnames(df)) {
60 if (length(base::unique(df$query)) > 1) {
61 df <- df %>% mutate(condition = query)
Marc Kupietzcf1771d2020-03-04 16:03:04 +010062 if(length(base::unique(queryStringToLabel(df$vc, excludePubDate = TRUE ))) > 1) {
Marc Kupietz91145b02020-01-29 15:58:36 +010063 df <- df %>% mutate(condition = paste(condition, " & ",
Marc Kupietzcf1771d2020-03-04 16:03:04 +010064 queryStringToLabel(vc, excludePubDate = TRUE )))
Marc Kupietz91145b02020-01-29 15:58:36 +010065 }
66 } else {
Marc Kupietz5d70ffe2020-03-12 11:16:43 +010067 if (length(base::unique(queryStringToLabel(df$vc, excludePubDate = TRUE ))) > 1) {
68 title <- base::unique(df$query)
Marc Kupietzb7e7f722020-06-02 12:29:18 +020069 df <- df %>% add_column(condition = queryStringToLabel(vc, excludePubDate = TRUE ))
Marc Kupietz5d70ffe2020-03-12 11:16:43 +010070 } else {
71 df <- df %>% mutate(condition = query)
Marc Kupietz91145b02020-01-29 15:58:36 +010072 }
73 }
74 }
75 # use the D3 palette which provides 20 attractive and distinguishable colours
76 palette <- c("#1F77B4", "#FF7F0E", "#2CA02C", "#D62728", "#9467BD", "#8C564B", "#E377C2", "#7F7F7F", "#BCBD22", "#17BECF", "#AEC7E8", "#FFBB78", "#98DF8A", "#FF9896", "#C5B0D5", "#C49C94", "#F7B6D2", "#C7C7C7", "#DBDB8D", "#9EDAE5")
77 highcharter::highchart() %>%
78 hc_title(text=title) %>%
Marc Kupietz91145b02020-01-29 15:58:36 +010079 hc_yAxis(
80 title = list(text = if (as.alternatives) "" else ylabel),
81 ceiling = if (as.alternatives) 100 else NULL,
82 floor = 0,
83 labels = if(as.alternatives) list(format = paste0("{value}\U2009", ylabel)) else NULL
84 ) %>%
Marc Kupietzcf1771d2020-03-04 16:03:04 +010085 hc_xAxis(allowDecimals=FALSE) %>%
Marc Kupietz91145b02020-01-29 15:58:36 +010086 hc_add_theme(hc_theme_google(colors=palette)) %>%
Marc Kupietze2038322021-03-04 18:24:02 +010087 hc_add_onclick_korap_search() %>%
Marc Kupietzcf1771d2020-03-04 16:03:04 +010088 hc_credits(enabled = TRUE,
Marc Kupietz900d0522020-03-19 13:36:45 +010089 text = "KorAP R Client Package",
90 href = "https://github.com/KorAP/RKorAPClient/") %>%
Marc Kupietzcf1771d2020-03-04 16:03:04 +010091 hc_exporting(enabled = TRUE) %>%
Marc Kupietz91145b02020-01-29 15:58:36 +010092 hc_tooltip(
Marc Kupietzab0b0712020-05-04 16:24:57 +020093 headerFormat = '<span style="font-size: 10pt">{point.key}</span><br/>',
Marc Kupietz91145b02020-01-29 15:58:36 +010094 formatter = JS(paste0("function (tooltip) {
95 var str = tooltip.defaultFormatter.call(this, tooltip);
96 if(Array.isArray(str)) {
97 str = str.join('');
98 }
99 for (var i = 0; i < this.points.length; i++) {
100 str = str.replace(/([0-9.,]+.?)", ylabel, "/, this.points[i].point.count+' ($1@)');
101 }
102 return str.replace(/@/g, '", ylabel, "')
103 } ")),
Marc Kupietzcf1771d2020-03-04 16:03:04 +0100104 crosshairs = TRUE,
Marc Kupietz91145b02020-01-29 15:58:36 +0100105 valueDecimals = 2,
Marc Kupietzcf1771d2020-03-04 16:03:04 +0100106 shared = TRUE,
Marc Kupietz91145b02020-01-29 15:58:36 +0100107 valueSuffix = paste0('\U2009', ylabel)
108 ) %>%
Marc Kupietzab0b0712020-05-04 16:24:57 +0200109 hc_add_series_korap_frequencies(df, smooth, as.alternatives, ...)
Marc Kupietz91145b02020-01-29 15:58:36 +0100110}
111
Marc Kupietza4f36532020-02-03 22:50:08 +0100112## Mute notes: "no visible binding for global variable:"
113globalVariables(c("value", "query", "condition", "vc"))
114
Marc Kupietzab0b0712020-05-04 16:24:57 +0200115hc_add_series_korap_frequencies <- function(hc, df, smooth = FALSE,
116 as.alternatives = FALSE,
117 ...) {
Marc Kupietz91145b02020-01-29 15:58:36 +0100118 index <- 0
Marc Kupietzab0b0712020-05-04 16:24:57 +0200119 type <- ifelse(smooth, "spline", "line")
120 areatype <- ifelse(smooth, "areasplinerange", "arearange")
Marc Kupietz91145b02020-01-29 15:58:36 +0100121 for(q in unique(df$condition)) {
122 dat <- df[df$condition==q,]
123 hc <- hc %>% hc_add_series(
124 marker = list(radius = 2),
125 name = q,
126 data = data.frame(
127 year = dat$year,
128 value = if (as.alternatives) dat$f else dat$ipm,
129 count = dat$totalResults,
Marc Kupietze2038322021-03-04 18:24:02 +0100130 webUIRequestUrl = dat$webUIRequestUrl
Marc Kupietz91145b02020-01-29 15:58:36 +0100131 ),
132 hcaes(year, value),
Marc Kupietzab0b0712020-05-04 16:24:57 +0200133 type = type,
Marc Kupietz91145b02020-01-29 15:58:36 +0100134 colorIndex = index,
Marc Kupietz5b503f42020-04-09 15:26:00 +0200135 zIndex = 1,
136 ...
Marc Kupietz91145b02020-01-29 15:58:36 +0100137 ) %>%
138 hc_add_series(
139 name = "ci",
140 data = dat[,c('year', 'conf.low', 'conf.high')],
141 hcaes(x = year, low = conf.low, high = conf.high),
Marc Kupietzab0b0712020-05-04 16:24:57 +0200142 type = areatype,
Marc Kupietz91145b02020-01-29 15:58:36 +0100143 fillOpacity = 0.3,
144 lineWidth = 0,
Marc Kupietzcf1771d2020-03-04 16:03:04 +0100145 marker = list(enabled = FALSE),
146 enableMouseTracking = FALSE,
Marc Kupietz91145b02020-01-29 15:58:36 +0100147 linkedTo= ':previous',
148 colorIndex = index,
149 zIndex = 0
150 )
151 index <- index+1
152 }
153 hc
154}
Marc Kupietz882f08c2020-03-18 13:30:31 +0100155
Marc Kupietze2038322021-03-04 18:24:02 +0100156#' Add KorAP search click events to highchart
157#'
158#' @description
159#' Adds on-click events to data points of highcarts that were constructed with
Marc Kupietza6e4ee62021-03-05 09:00:15 +0100160#' \code{\link{frequencyQuery}} or \code{\link{collocationScoreQuery}}. Clicks on data points
Marc Kupietze2038322021-03-04 18:24:02 +0100161#' then launch KorAP web UI queries for the given query term and virtual corpus in
Marc Kupietza6e4ee62021-03-05 09:00:15 +0100162#' a separate tab.
Marc Kupietze2038322021-03-04 18:24:02 +0100163#'
Marc Kupietza6e4ee62021-03-05 09:00:15 +0100164#' @rdname highcharter-helpers
Marc Kupietze2038322021-03-04 18:24:02 +0100165#' @export
166#'
167#' @examples
168#' \donttest{
169#' library(highcharter)
170#' library(tidyr)
171#'
172#' new("KorAPConnection", verbose = TRUE) %>%
173#' collocationScoreQuery("Team", "agil", vc = paste("pubDate in", c(2014:2018)),
174#' lemmatizeNodeQuery = TRUE, lemmatizeCollocateQuery = TRUE) %>%
175#' pivot_longer(c("O", "E")) %>%
176#' hchart(type="spline", hcaes(label, value, group=name)) %>%
177#' hc_add_onclick_korap_search()
178#' }
179#'
180hc_add_onclick_korap_search <- function(hc) {
181 hc_plotOptions(
182 hc,
183 series = list(enabled = TRUE),
184 spline = list(cursor = 'pointer', point = list(events = list(
185 click = JS("function() { window.open(this.webUIRequestUrl, 'korap'); }")
186 ))),
187 line = list(cursor = 'pointer', point = list(events = list(
188 click = JS("function() { window.open(this.webUIRequestUrl, 'korap'); }")
189 ))))
190}
191
Marc Kupietz882f08c2020-03-18 13:30:31 +0100192.onAttach <- function(libname = find.package("RKorAPClient"),
193 pkgname = "RKorAPClient") {
194 packageStartupMessage(
195 "If you intend to use the Highcharts plot options, please note that Highcharts (www.highcharts.com) is a Highsoft software product which is not free for commercial and governmental use."
196 )
197}
198