|  |  | 
					
						
						|  | filter_data <- function(data, input, return_columns = NULL) { | 
					
						
						|  |  | 
					
						
						|  | if (length(input$column) == 0) { | 
					
						
						|  | return(data[0]) | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | filtered_data <- data[ | 
					
						
						|  | Annee_unique >= input$date_range[1] & | 
					
						
						|  | Annee_unique <= input$date_range[2] | 
					
						
						|  | ] | 
					
						
						|  |  | 
					
						
						|  | pattern <- input$motcle | 
					
						
						|  | matches <- rep(FALSE, nrow(filtered_data)) | 
					
						
						|  |  | 
					
						
						|  | for (col in input$column) { | 
					
						
						|  | if (input$regex) { | 
					
						
						|  | matches <- matches | grepl(pattern, filtered_data[[col]], ignore.case = TRUE) | 
					
						
						|  | } else { | 
					
						
						|  | matches <- matches | grepl(pattern, filtered_data[[col]], fixed = TRUE, ignore.case = TRUE) | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | filtered_data <- filtered_data[matches, ] | 
					
						
						|  |  | 
					
						
						|  | if (!is.null(return_columns)) { | 
					
						
						|  | filtered_data <- filtered_data[, ..return_columns] | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | return(filtered_data) | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | plot_histogram <- function(data_frame) { | 
					
						
						|  | if ("Annee_unique" %in% names(data_frame) && nrow(data_frame) > 0) { | 
					
						
						|  | min_year <- min(na.omit(data_frame[, Annee_unique])) | 
					
						
						|  | max_year <- max(na.omit(data_frame[, Annee_unique])) | 
					
						
						|  | breaks_hist <- seq(min_year, max_year, length.out = input$num_breaks + 1) | 
					
						
						|  |  | 
					
						
						|  | if (input$dist_type == "raw") { | 
					
						
						|  | hist(data_frame()[, Annee_unique], | 
					
						
						|  | main = "Distribution brute des notices", | 
					
						
						|  | xlab = "Année", | 
					
						
						|  | ylab = "Nombre", | 
					
						
						|  | border = "blue", | 
					
						
						|  | col = "lightblue", | 
					
						
						|  | breaks = breaks_hist) | 
					
						
						|  | } else { | 
					
						
						|  |  | 
					
						
						|  | filtered_counts <- hist(data_frame[, Annee_unique], plot=FALSE, breaks=breaks_hist)$counts | 
					
						
						|  | total_counts <- hist(data[data$Annee_unique %in% data_frame[, Annee_unique], Annee_unique], plot=FALSE, breaks=breaks_hist)$counts | 
					
						
						|  | relative_counts <- ifelse(total_counts == 0, 0, filtered_counts / total_counts) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | names_for_bars <- round(seq(min_year, max_year, length.out = length(relative_counts))) | 
					
						
						|  |  | 
					
						
						|  | barplot(relative_counts, | 
					
						
						|  | main = "Distribution relative des notices", | 
					
						
						|  | xlab = "Année", | 
					
						
						|  | ylab = "Fréquence relative", | 
					
						
						|  | border = "blue", | 
					
						
						|  | col = "lightblue", | 
					
						
						|  | space = 0, | 
					
						
						|  | names.arg = names_for_bars) | 
					
						
						|  | } | 
					
						
						|  | } else { | 
					
						
						|  | plot.new() | 
					
						
						|  | title(main = "No data available for the selected criteria") | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | inst_ext_f <- function(extension) { | 
					
						
						|  | if(!extension %in% rownames(installed.packages())) { | 
					
						
						|  | install.packages(extension, dependencies = TRUE) | 
					
						
						|  | } | 
					
						
						|  | require(extension, character.only = TRUE) | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | extensions <- c("shiny", | 
					
						
						|  | "data.table", | 
					
						
						|  | "DT", | 
					
						
						|  | "shinyWidgets", | 
					
						
						|  | "stringr", | 
					
						
						|  | "markdown") | 
					
						
						|  |  | 
					
						
						|  | sapply(extensions, inst_ext_f) | 
					
						
						|  |  | 
					
						
						|  | data <- readRDS("dolq_min.RDS") |> setDT() | 
					
						
						|  |  | 
					
						
						|  | readme_content <- readLines("README.md", warn = FALSE) | 
					
						
						|  |  | 
					
						
						|  | ui <- fluidPage( | 
					
						
						|  | titlePanel("Dictionnaire des oeuvres littéraires du Québec, t. 1-6"), | 
					
						
						|  | tabsetPanel( | 
					
						
						|  | tabPanel("Recherche plein texte", | 
					
						
						|  | sidebarLayout( | 
					
						
						|  | sidebarPanel( | 
					
						
						|  | noUiSliderInput(inputId = "date_range", | 
					
						
						|  | label = "Sélectionner une période:", | 
					
						
						|  | min = 1830, | 
					
						
						|  | max = 1980, | 
					
						
						|  | value = c(1830, 1980), | 
					
						
						|  | format = wNumbFormat(decimals = 0), | 
					
						
						|  | tooltips = TRUE), | 
					
						
						|  | br(), | 
					
						
						|  |  | 
					
						
						|  | pickerInput( | 
					
						
						|  | inputId = "column", | 
					
						
						|  | label = h5("Choisissez les colonnes où effectuer la recherche:"), | 
					
						
						|  | choices = c("Auteur_oeuvre", "Titre", "Auteur_notice", "Article", | 
					
						
						|  | "Depouillement", "Details_bibliographiques"), | 
					
						
						|  | selected = "Article", | 
					
						
						|  | options = list(`actions-box` = TRUE), | 
					
						
						|  | multiple = TRUE | 
					
						
						|  | ), | 
					
						
						|  | pickerInput( | 
					
						
						|  | inputId = "additional_columns", | 
					
						
						|  | label = h5("Choisissez les colonnes à afficher:"), | 
					
						
						|  | choices = c("Id", "Auteur_oeuvre", "Titre", "Annee_parution",  "Auteur_notice", "Article", "Volume", "Depouillement", "Details_bibliographiques"), | 
					
						
						|  | selected = c("Auteur_oeuvre", "Titre", "Article"), | 
					
						
						|  | options = list(`actions-box` = TRUE), | 
					
						
						|  | multiple = TRUE | 
					
						
						|  | ), | 
					
						
						|  | textInput( | 
					
						
						|  | inputId = "motcle", | 
					
						
						|  | label = h5("Chaine de caractères à rechercher"), | 
					
						
						|  | value = "Montréal" | 
					
						
						|  | ), | 
					
						
						|  | prettySwitch( | 
					
						
						|  | inputId = "regex", | 
					
						
						|  | label = "Utiliser une expression régulière?", | 
					
						
						|  | fill = FALSE, | 
					
						
						|  | status = "primary" | 
					
						
						|  | ), | 
					
						
						|  | downloadButton("downloadData", "Exporter le résultat de la table (csv)"), | 
					
						
						|  | width = 4, | 
					
						
						|  | hr(), | 
					
						
						|  |  | 
					
						
						|  | tags$head(tags$link(rel = "stylesheet", href = "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css")), | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | h5("Antisèche - expressions régulières"), | 
					
						
						|  | tags$a(href = "regex.pdf", target = "_blank", | 
					
						
						|  | tags$img(src = "regex.jpg", alt = "Thumbnail", width = "100%")), | 
					
						
						|  |  | 
					
						
						|  | hr(), | 
					
						
						|  | h5("Accéder aux volumes (pdf)"), | 
					
						
						|  |  | 
					
						
						|  | tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-1-des-origines-a-1900/", target = "_blank", | 
					
						
						|  | tags$img(src = "DOLQ_01.jpg", alt = "Volume 1", width = "50%")), | 
					
						
						|  | tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-2-1900-a-1939/", target = "_blank", | 
					
						
						|  | tags$img(src = "DOLQ_02.jpg", alt = "Volume 2", width = "50%")), | 
					
						
						|  | tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-3-1940-a-1959/", target = "_blank", | 
					
						
						|  | tags$img(src = "DOLQ_03.jpg", alt = "Volume 3", width = "50%")), | 
					
						
						|  | tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-4-1960-1969/", target = "_blank", | 
					
						
						|  | tags$img(src = "DOLQ_04.jpg", alt = "Volume 4", width = "50%")), | 
					
						
						|  | tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-5-1970-1975/", target = "_blank", | 
					
						
						|  | tags$img(src = "DOLQ_05.jpg", alt = "Volume 5", width = "50%")), | 
					
						
						|  | tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-5-1970-1975/", target = "_blank", | 
					
						
						|  | tags$img(src = "DOLQ_06.jpg", alt = "Volume 6", width = "50%")), | 
					
						
						|  | ), | 
					
						
						|  |  | 
					
						
						|  | mainPanel(h3("Distribution chronologique des notices"), | 
					
						
						|  |  | 
					
						
						|  | radioButtons(inputId = "dist_type", | 
					
						
						|  | label = "Type de distribution:", | 
					
						
						|  | choices = list("Distribution brute" = "raw", | 
					
						
						|  | "Distribution relative" = "relative"), | 
					
						
						|  | selected = "raw"), | 
					
						
						|  |  | 
					
						
						|  | numericInput("num_breaks", label = "Nombre d'intervalles:", value = 65, min = 1), | 
					
						
						|  |  | 
					
						
						|  | plotOutput("histogram"), | 
					
						
						|  |  | 
					
						
						|  | downloadButton("download_graph", "Exporter le graphique"), | 
					
						
						|  | downloadButton("download_table", "Exporter les données du graphique"), | 
					
						
						|  |  | 
					
						
						|  | h3("Table"), | 
					
						
						|  | textOutput("filtered_count"), | 
					
						
						|  | DT::dataTableOutput('table')) | 
					
						
						|  | ) | 
					
						
						|  | ), | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | tabPanel("Documentation", | 
					
						
						|  | uiOutput("readme") | 
					
						
						|  | ) | 
					
						
						|  | ) | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | server <- function(input, output) { | 
					
						
						|  |  | 
					
						
						|  | reactive_data <- reactive({ | 
					
						
						|  | filter_data(data, input, input$additional_columns) | 
					
						
						|  | }) | 
					
						
						|  |  | 
					
						
						|  | reactive_data1 <- reactive({ | 
					
						
						|  | filter_data(data, input) | 
					
						
						|  | }) | 
					
						
						|  |  | 
					
						
						|  | filtered_count <- reactive({ | 
					
						
						|  | nrow(reactive_data()) | 
					
						
						|  | }) | 
					
						
						|  |  | 
					
						
						|  | hist_data <- reactive({ | 
					
						
						|  | if ("Annee_unique" %in% names(reactive_data1()) && nrow(reactive_data1()) > 0) { | 
					
						
						|  |  | 
					
						
						|  | data_numeric <- as.numeric(reactive_data1()[, Annee_unique]) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | data_numeric <- na.omit(data_numeric) | 
					
						
						|  |  | 
					
						
						|  | if (length(data_numeric) > 0) { | 
					
						
						|  | min_year <- min(data_numeric) | 
					
						
						|  | max_year <- max(data_numeric) | 
					
						
						|  | breaks_hist <- seq(min_year, max_year, length.out = input$num_breaks + 1) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | raw_counts <- hist(data_numeric, plot=FALSE, breaks=breaks_hist)$counts | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | total_counts <- hist(data[data$Annee_unique %in% reactive_data1()[, Annee_unique], Annee_unique], plot=FALSE, breaks=breaks_hist)$counts | 
					
						
						|  |  | 
					
						
						|  | relative_counts <- ifelse(total_counts == 0, 0, raw_counts / total_counts) | 
					
						
						|  |  | 
					
						
						|  | breaks <- round(seq(min_year, max_year, length.out = length(raw_counts))) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | if (input$dist_type == "raw") { | 
					
						
						|  | return(data.frame(Breaks = breaks, Counts = raw_counts)) | 
					
						
						|  | } else { | 
					
						
						|  | return(data.frame(Breaks = breaks, RelativeCounts = relative_counts)) | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | return(data.frame(Breaks = numeric(0), Counts = numeric(0))) | 
					
						
						|  | }) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | output$filtered_count <- renderText({ | 
					
						
						|  | paste("Nombre de notices filtrées:", filtered_count()) | 
					
						
						|  | }) | 
					
						
						|  |  | 
					
						
						|  | output$table <- DT::renderDataTable({ | 
					
						
						|  | datatable(reactive_data(), options = list(searching = FALSE), | 
					
						
						|  | callback = JS(paste0(" | 
					
						
						|  | table.on('draw.dt', function() { | 
					
						
						|  | var keyword = '", input$motcle, "'; | 
					
						
						|  | $('td').each(function() { | 
					
						
						|  | var content = $(this).html(); | 
					
						
						|  | var highlighted = content.replace(new RegExp(keyword, 'gi'), function(match) { | 
					
						
						|  | return '<span style=\"background-color: yellow;\">' + match + '</span>'; | 
					
						
						|  | }); | 
					
						
						|  | $(this).html(highlighted); | 
					
						
						|  | }); | 
					
						
						|  | }); | 
					
						
						|  | "))) | 
					
						
						|  | }) | 
					
						
						|  |  | 
					
						
						|  | output$downloadData <- downloadHandler( | 
					
						
						|  | filename = function() { | 
					
						
						|  | paste("filtered_data-", Sys.Date(), ".csv", sep="") | 
					
						
						|  | }, | 
					
						
						|  | content = function(file) { | 
					
						
						|  | fwrite(reactive_data(), file) | 
					
						
						|  | } | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | output$histogram <- renderPlot({ | 
					
						
						|  |  | 
					
						
						|  | if ("Annee_unique" %in% names(reactive_data1()) && nrow(reactive_data1()) > 0) { | 
					
						
						|  | min_year <- min(na.omit(reactive_data1()[, Annee_unique])) | 
					
						
						|  | max_year <- max(na.omit(reactive_data1()[, Annee_unique])) | 
					
						
						|  | breaks_hist <- seq(min_year, max_year, length.out = input$num_breaks + 1) | 
					
						
						|  |  | 
					
						
						|  | if (input$dist_type == "raw") { | 
					
						
						|  | hist(reactive_data1()[, Annee_unique], | 
					
						
						|  | main = "Distribution brute des notices", | 
					
						
						|  | xlab = "Année", | 
					
						
						|  | ylab = "Nombre", | 
					
						
						|  | border = "blue", | 
					
						
						|  | col = "lightblue", | 
					
						
						|  | breaks = breaks_hist) | 
					
						
						|  | } else { | 
					
						
						|  |  | 
					
						
						|  | filtered_counts <- hist(reactive_data1()[, Annee_unique], plot=FALSE, breaks=breaks_hist)$counts | 
					
						
						|  | total_counts <- hist(data[data$Annee_unique %in% reactive_data1()[, Annee_unique], Annee_unique], plot=FALSE, breaks=breaks_hist)$counts | 
					
						
						|  | relative_counts <- ifelse(total_counts == 0, 0, filtered_counts / total_counts) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | names_for_bars <- round(seq(min_year, max_year, length.out = length(relative_counts))) | 
					
						
						|  |  | 
					
						
						|  | barplot(relative_counts, | 
					
						
						|  | main = "Distribution relative des notices", | 
					
						
						|  | xlab = "Année", | 
					
						
						|  | ylab = "Fréquence relative", | 
					
						
						|  | border = "blue", | 
					
						
						|  | col = "lightblue", | 
					
						
						|  | space = 0, | 
					
						
						|  | names.arg = names_for_bars) | 
					
						
						|  | } | 
					
						
						|  | } else { | 
					
						
						|  | plot.new() | 
					
						
						|  | title(main = "No data available for the selected criteria") | 
					
						
						|  | } | 
					
						
						|  | }) | 
					
						
						|  |  | 
					
						
						|  | output$download_graph <- downloadHandler( | 
					
						
						|  | filename = function() { | 
					
						
						|  | paste("histogram_graph", Sys.Date(), ".png", sep = "_") | 
					
						
						|  | }, | 
					
						
						|  | content = function(file) { | 
					
						
						|  | png(file) | 
					
						
						|  |  | 
					
						
						|  | if ("Annee_unique" %in% names(reactive_data1()) && nrow(reactive_data1()) > 0) { | 
					
						
						|  | min_year <- min(na.omit(reactive_data1()[, Annee_unique])) | 
					
						
						|  | max_year <- max(na.omit(reactive_data1()[, Annee_unique])) | 
					
						
						|  | breaks_hist <- seq(min_year, max_year, length.out = input$num_breaks + 1) | 
					
						
						|  |  | 
					
						
						|  | if (input$dist_type == "raw") { | 
					
						
						|  | hist(reactive_data1()[, Annee_unique], | 
					
						
						|  | main = "Distribution brute des notices", | 
					
						
						|  | xlab = "Année", | 
					
						
						|  | ylab = "Nombre", | 
					
						
						|  | border = "blue", | 
					
						
						|  | col = "lightblue", | 
					
						
						|  | breaks = breaks_hist) | 
					
						
						|  | } else { | 
					
						
						|  |  | 
					
						
						|  | filtered_counts <- hist(reactive_data1()[, Annee_unique], plot=FALSE, breaks=breaks_hist)$counts | 
					
						
						|  | total_counts <- hist(data[data$Annee_unique %in% reactive_data1()[, Annee_unique], Annee_unique], plot=FALSE, breaks=breaks_hist)$counts | 
					
						
						|  | relative_counts <- ifelse(total_counts == 0, 0, filtered_counts / total_counts) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | names_for_bars <- round(seq(min_year, max_year, length.out = length(relative_counts))) | 
					
						
						|  |  | 
					
						
						|  | barplot(relative_counts, | 
					
						
						|  | main = "Distribution relative des notices", | 
					
						
						|  | xlab = "Année", | 
					
						
						|  | ylab = "Fréquence relative", | 
					
						
						|  | border = "blue", | 
					
						
						|  | col = "lightblue", | 
					
						
						|  | space = 0, | 
					
						
						|  | names.arg = names_for_bars) | 
					
						
						|  | } | 
					
						
						|  | } else { | 
					
						
						|  | plot.new() | 
					
						
						|  | title(main = "No data available for the selected criteria") | 
					
						
						|  | } | 
					
						
						|  | dev.off() | 
					
						
						|  | } | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  | output$download_table <- downloadHandler( | 
					
						
						|  | filename = function() { | 
					
						
						|  | paste("histogram_data", Sys.Date(), ".csv", sep = "_") | 
					
						
						|  | }, | 
					
						
						|  | content = function(file) { | 
					
						
						|  | write.csv(hist_data(), file, row.names = FALSE) | 
					
						
						|  | } | 
					
						
						|  | ) | 
					
						
						|  | output$readme <- renderUI({ | 
					
						
						|  |  | 
					
						
						|  | readme_content <- readLines("README.md", warn = FALSE) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | HTML(markdown::markdownToHTML(text = readme_content, fragment.only = TRUE)) | 
					
						
						|  | }) | 
					
						
						|  |  | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | shinyApp(ui = ui, server = server) |