diff --git a/inst/AntaresViz.xlsx b/inst/AntaresViz.xlsx new file mode 100644 index 0000000..47b0150 Binary files /dev/null and b/inst/AntaresViz.xlsx differ diff --git a/inst/GraphicalCharter.csv b/inst/GraphicalCharter.csv index b3a88fd..19c2e20 100644 --- a/inst/GraphicalCharter.csv +++ b/inst/GraphicalCharter.csv @@ -1,29 +1,29 @@ -name red green blue formula -pumpedStorage 17 71 185 PSP -"import/export" 150 150 150 -(BALANCE + `ROW BAL.`) -mustRunTotal 120 136 194 mustRunTotal -mustRunPartial 120 236 194 mustRunPartial -mustRun 220 236 94 mustRun -bioenergy 22 106 87 `MISC. NDG` -wind 116 205 185 WIND -solar 242 116 6 SOLAR -nuclear 245 179 0 NUCLEAR -hydraulic 39 114 178 `H. ROR`+`H. STOR` -gas 243 10 10 GAS -coal 172 140 53 COAL -other 173 255 47 `MISC. DTG` + `MIX. FUEL` -load 135 86 39 LOAD -renewable 0 255 0 WIND+SOLAR+`H. ROR`+`H. STOR`+`MISC. NDG` -renewableNoDispatchable 0 255 0 WIND+SOLAR+`H. ROR`+`MISC. NDG` -thermal 77 77 77 NUCLEAR+LIGNITE+COAL+GAS+OIL+`MIX. FUEL`+`MISC. DTG` -thermalDispatchable 100 100 100 NUCLEAR+LIGNITE+COAL+GAS+OIL+`MIX. FUEL`+`MISC. DTG` -hydraulicDispatchable 39 114 178 `H. STOR` -lignite 180 130 43 LIGNITE -oil 131 86 162 OIL -mixFuel 127 84 156 `MIX. FUEL` -"misc. DTG" 173 255 47 `MISC. DTG` -hydraulicRor 61 96 125 `H. ROR` -hydraulicStor 84 151 208 `H. STOR` -totalProduction 235 155 166 NUCLEAR+LIGNITE+COAL+GAS+OIL+`MIX. FUEL`+`MISC. DTG`+WIND+SOLAR+`H. ROR`+`H. STOR`+`MISC. NDG` + pmax(0, PSP) -netLoad 101 180 197 netLoad -thermalAvailability 1 1 1 `AVL DTG` \ No newline at end of file +name;red;green;blue;formula;Needed_Col +pumpedStorage;17;71;185;PSP;PSP +import/export;150;150;150;-(BALANCE + `ROW BAL.`);BALANCE,ROW BAL. +mustRunTotal;120;136;194;mustRunTotal;mustRunTotal +mustRunPartial;120;236;194;mustRunPartial;mustRunPartial +mustRun;220;236;94;mustRun;mustRun +bioenergy;22;106;87;`MISC. NDG`;MISC. NDG +wind;116;205;185;WIND;WIND +solar;242;116;6;SOLAR;SOLAR +nuclear;245;179;0;NUCLEAR;NUCLEAR +hydraulic;39;114;178;`H. ROR`+`H. STOR`;H. ROR,H. STOR +gas;243;10;10;GAS;GAS +coal;172;140;53;COAL;COAL +other;173;255;47;`MISC. DTG` + `MIX. FUEL`;MISC. DTG,MIX. FUEL +load;135;86;39;LOAD;LOAD +renewable;0;255;0;WIND+SOLAR+`H. ROR`+`H. STOR`+`MISC. NDG`;WIND,SOLAR,H. ROR,H. STOR,MISC. NDG +renewableNoDispatchable;0;255;0;WIND+SOLAR+`H. ROR`+`MISC. NDG`;WIND,SOLAR,H. ROR,MISC. NDG +thermal;77;77;77;NUCLEAR+LIGNITE+COAL+GAS+OIL+`MIX. FUEL`+`MISC. DTG`;NUCLEAR,LIGNITE,COAL,GAS,OIL,MIX. FUEL,MISC. DTG +thermalDispatchable;100;100;100;NUCLEAR+LIGNITE+COAL+GAS+OIL+`MIX. FUEL`+`MISC. DTG`;NUCLEAR,LIGNITE,COAL,GAS,OIL,MIX. FUEL,MISC. DTG +hydraulicDispatchable;39;114;178;`H. STOR`;H. STOR +lignite;180;130;43;LIGNITE;LIGNITE +oil;131;86;162;OIL;OIL +mixFuel;127;84;156;`MIX. FUEL`;MIX. FUEL +misc. DTG;173;255;47;`MISC. DTG`;MISC. DTG +hydraulicRor;61;96;125;`H. ROR`;H. ROR +hydraulicStor;84;151;208;`H. STOR`;H. STOR +totalProduction;235;155;166;NUCLEAR+LIGNITE+COAL+GAS+OIL+`MIX. FUEL`+`MISC. DTG`+WIND+SOLAR+`H. ROR`+`H. STOR`+`MISC. NDG` + pmax(0, PSP);NUCLEAR,LIGNITE,COAL,GAS,OIL,MIX. FUEL,MISC. DTG,WIND,SOLAR,H. ROR,H. STOR,MISC. NDG,PSP +netLoad;101;180;197;netLoad;netLoad +thermalAvailability;1;1;1;`AVL DTG`;AVL DTG diff --git a/inst/application/global.R b/inst/application/global.R new file mode 100644 index 0000000..aa08f50 --- /dev/null +++ b/inst/application/global.R @@ -0,0 +1,79 @@ +require(shiny) +require(antaresRead) +require(antaresViz) +require(manipulateWidget) +require(data.table) + + +# choose a directory +source("src/scripts/directoryInput.R") + +# shared inputs +.global_shared_prodStack <- data.frame( + module = "prodStack", + panel = "prodStack", + input = c("dateRange", "unit", "mcYear", "mcYearh", "timeSteph5", "legend", "drawPoints", "stepPlot"), + type = c("dateRangeInput", "selectInput", "selectInput", "selectInput", "selectInput", + "checkboxInput", "checkboxInput", "checkboxInput"), stringsAsFactors = FALSE) + +.global_shared_plotts <- data.frame( + module = "plotts", + panel = "tsPlot", + input = c("dateRange", "mcYear", "mcYearh", "timeSteph5", "legend", "drawPoints", "stepPlot"), + type = c("dateRangeInput", "selectInput", "selectInput", "selectInput", + "checkboxInput", "checkboxInput", "checkboxInput"), stringsAsFactors = FALSE) + + +.global_shared_plotMap <- data.frame( + module = "plotMap", + panel = "Map", + input = c("dateRange", "mcYear", "mcYearh", "timeSteph5"), + type = c("dateRangeInput", "selectInput", "selectInput", "selectInput"), stringsAsFactors = FALSE) + +.global_shared_exchangesStack <- data.frame( + module = "exchangesStack", + panel = "exchangesStack", + input = c("dateRange", "unit", "mcYear", "mcYearh", "timeSteph5", "legend", "drawPoints", "stepPlot"), + type = c("dateRangeInput", "selectInput", "selectInput", "selectInput", "selectInput", + "checkboxInput", "checkboxInput", "checkboxInput"), stringsAsFactors = FALSE) + +.global_shared_input <- rbind(.global_shared_prodStack, .global_shared_plotts, .global_shared_plotMap, .global_shared_exchangesStack) + + +.global_build_input_data <- function(data){ + data$input_id <- paste0(data$module, "-shared_", data$input) + data$last_update <- NA + data$update_call <- "" + class(data$last_update) <- c("character") + data <- data.table(data) + data +} + +#------------ +# compare +#----------- + +.global_compare_prodstack <- c("mcYear", "main", "unit", "areas", "legend", + "stack", "stepPlot", "drawPoints") + +.global_compare_exchangesStack <- c("mcYear", "main", "unit", "area", + "legend", "stepPlot", "drawPoints") + +.global_compare_tsPlot <- c("mcYear", "main", "variable", "type", "confInt", "elements", + "aggregate", "legend", "highlight", "stepPlot", "drawPoints", "secondAxis") + +.global_compare_plotMap <- c("mcYear", "type", "colAreaVar", "sizeAreaVars", "areaChartType", "showLabels", + "popupAreaVars", "labelAreaVar","colLinkVar", "sizeLinkVar", "popupLinkVars") + + +#----- generate help for antaresRead function +# library(tools) +# add.html.help <- function(package, func, tempsave = paste0(getwd(), "/temp.html")) { +# pkgRdDB = tools:::fetchRdDB(file.path(find.package(package), "help", package)) +# topics = names(pkgRdDB) +# rdfunc <- pkgRdDB[[func]] +# tools::Rd2HTML(pkgRdDB[[func]], out = tempsave) +# } +# add.html.help("antaresRead", "readAntares", "inst/application/www/readAntares.html") +# add.html.help("antaresRead", "removeVirtualAreas", "inst/application/www/removeVirtualAreas.html") +# add.html.help("antaresRead", "writeAntaresH5", "inst/application/www/writeAntaresH5.html") diff --git a/inst/application/src/scripts/directoryInput.R b/inst/application/src/scripts/directoryInput.R new file mode 100644 index 0000000..3e0df04 --- /dev/null +++ b/inst/application/src/scripts/directoryInput.R @@ -0,0 +1,169 @@ +#' Choose a Folder Interactively (Mac OS X) +#' +#' Display a folder selection dialog under Mac OS X +#' +#' @param default which folder to show initially +#' @param caption the caption on the selection dialog +#' +#' @details +#' Uses an Apple Script to display a folder selection dialog. With \code{default = NA}, +#' the initial folder selection is determined by default behavior of the +#' "choose folder" Apple Script command. Otherwise, paths are expanded with +#' \link{path.expand}. +#' +#' @return +#' A length one character vector, character NA if 'Cancel' was selected. +#' +if (Sys.info()['sysname'] == 'Darwin') { + choose.dir = function(default = NA, caption = NA) { + command = 'osascript' + args = '-e "POSIX path of (choose folder{{prompt}}{{default}})"' + + if (!is.null(caption) && !is.na(caption) && nzchar(caption)) { + prompt = sprintf(' with prompt \\"%s\\"', caption) + } else { + prompt = '' + } + args = sub('{{prompt}}', prompt, args, fixed = T) + + if (!is.null(default) && !is.na(default) && nzchar(default)) { + default = sprintf(' default location \\"%s\\"', path.expand(default)) + } else { + default = '' + } + args = sub('{{default}}', default, args, fixed = T) + + suppressWarnings({ + path = system2(command, args = args, stderr = TRUE) + }) + if (!is.null(attr(path, 'status')) && attr(path, 'status')) { + # user canceled + path = NA + } + + return(path) + } +} else if (Sys.info()['sysname'] == 'Linux') { + choose.dir = function(default = NA, caption = NA) { + command = 'zenity' + args = '--file-selection --directory --title="Choose a folder"' + + suppressWarnings({ + path = system2(command, args = args, stderr = TRUE) + }) + + #Return NA if user hits cancel + if (!is.null(attr(path, 'status')) && attr(path, 'status')) { + # user canceled + return(default) + } + + #Error: Gtk-Message: GtkDialog mapped without a transient parent + if(length(path) == 2){ + path = path[2] + } + + return(path) + } +} + +#' Directory Selection Control +#' +#' Create a directory selection control to select a directory on the server +#' +#' @param inputId The \code{input} slot that will be used to access the value +#' @param label Display label for the control, or NULL for no label +#' @param value Initial value. Paths are exapnded via \code{\link{path.expand}}. +#' +#' @details +#' This widget relies on \link{\code{choose.dir}} to present an interactive +#' dialog to users for selecting a directory on the local filesystem. Therefore, +#' this widget is intended for shiny apps that are run locally - i.e. on the +#' same system that files/directories are to be accessed - and not from hosted +#' applications (e.g. from shinyapps.io). +#' +#' @return +#' A directory input control that can be added to a UI definition. +#' +#' @seealso +#' \link{updateDirectoryInput}, \link{readDirectoryInput}, \link[utils]{choose.dir} +directoryInput = function(inputId, label, value = NULL) { + if (!is.null(value) && !is.na(value)) { + value = path.expand(value) + } + + tagList( + singleton( + tags$head( + tags$script(src = 'js/directory_input_binding.js') + ) + ), + + div( + class = 'form-group directory-input-container', + shiny:::`%AND%`(label, tags$label(label)), + div( + span( + class = 'col-xs-9 col-md-11', + style = 'padding-left: 0; padding-right: 5px;', + div( + class = 'input-group shiny-input-container', + style = 'width:100%;', + div(class = 'input-group-addon', icon('folder-o')), + tags$input( + id = sprintf('%s__chosen_dir', inputId), + value = value, + type = 'text', + class = 'form-control directory-input-chosen-dir', + readonly = 'readonly' + ) + ) + ), + span( + class = 'shiny-input-container', + tags$button( + id = inputId, + class = 'btn btn-default directory-input', + '...' + ) + ) + ) + ) + + ) + +} + +#' Change the value of a directoryInput on the client +#' +#' @param session The \code{session} object passed to function given to \code{shinyServer}. +#' @param inputId The id of the input object. +#' @param value A directory path to set +#' @param ... Additional arguments passed to \link{\code{choose.dir}}. Only used +#' if \code{value} is \code{NULL}. +#' +#' @details +#' Sends a message to the client, telling it to change the value of the input +#' object. For \code{directoryInput} objects, this changes the value displayed +#' in the text-field and triggers a client-side change event. A directory +#' selection dialog is not displayed. +#' +updateDirectoryInput = function(session, inputId, value = NULL, ...) { + if (is.null(value)) { + value = choose.dir(...) + } + session$sendInputMessage(inputId, list(chosen_dir = value)) +} + +#' Read the value of a directoryInput +#' +#' @param session The \code{session} object passed to function given to \code{shinyServer}. +#' @param inputId The id of the input object +#' +#' @details +#' Reads the value of the text field associated with a \code{directoryInput} +#' object that stores the user selected directory path. +#' +readDirectoryInput = function(session, inputId) { + session$input[[sprintf('%s__chosen_dir', inputId)]] +} diff --git a/inst/application/src/server/02_load_data.R b/inst/application/src/server/02_load_data.R new file mode 100644 index 0000000..646e0c0 --- /dev/null +++ b/inst/application/src/server/02_load_data.R @@ -0,0 +1,159 @@ +#----------------- +# Importation de nouvelles donnees +#----------------- +observe({ + if(input$import_data > 0){ + isolate({ + if(!is.null(opts())){ + # not a .h5 file, so read data + if(!opts()$h5){ + # Treat mcYears + if(input$read_type_mcYears == "synthetic"){ + mcYears <- NULL + } else if(input$read_type_mcYears == "all"){ + mcYears <- "all" + } else { + mcYears <- as.numeric(input$read_mcYears) + } + + # import data + data <- withCallingHandlers({ + tryCatch({ + readAntares(areas = input$read_areas, links = input$read_links, clusters = input$read_clusters, + districts = input$read_districts, misc = input$read_misc, + thermalAvailabilities = input$read_thermalAvailabilities, + hydroStorage = input$read_hydroStorage, hydroStorageMaxPower = input$read_hydroStorageMaxPower, + reserve = input$read_reserve, linkCapacity = input$read_linkCapacity, + mustRun = input$read_mustRun, thermalModulation = input$read_thermalModulation, + select = input$read_select, mcYears = mcYears, timeStep = input$read_timeStep, + opts = opts(), + # parallel = input$read_parallel, + simplify = TRUE, showProgress = FALSE)}, + error = function(e){ + showModal(modalDialog( + title = "Error reading data", + easyClose = TRUE, + footer = NULL, + paste("Please update input. Error : ", e, sep = "\n") + )) + list() + })}, + warning = function(w){ + showModal(modalDialog( + title = "Warning reading data", + easyClose = TRUE, + footer = NULL, + w + )) + } + ) + + # removeVirtualAreas + if(input$rmva_ctrl){ + if(length(data) > 0){ + data <- withCallingHandlers({ + tryCatch({ + removeVirtualAreas(x = data, + storageFlexibility = input$rmva_storageFlexibility, + production = input$rmva_production, + reassignCosts = input$rmva_reassignCosts, + newCols = input$rmva_newCols)}, + error = function(e){ + showModal(modalDialog( + title = "removeVirtualAreas : error", + easyClose = TRUE, + footer = NULL, + paste("Please update input. Error : ", e, sep = "\n") + )) + list() + })}, + warning = function(w){ + showModal(modalDialog( + title = "removeVirtualAreas : warning", + easyClose = TRUE, + footer = NULL, + w + )) + } + ) + } + } + + if(length(data) > 0){ + # save params + params <- list( + areas = input$read_areas, links = input$read_links, clusters = input$read_clusters, + districts = input$read_districts, misc = input$read_misc, + thermalAvailabilities = input$read_thermalAvailabilities, + hydroStorage = input$read_hydroStorage, hydroStorageMaxPower = input$read_hydroStorageMaxPower, + reserve = input$read_reserve, linkCapacity = input$read_linkCapacity, + mustRun = input$read_mustRun, thermalModulation = input$read_thermalModulation, + select = input$read_select, mcYears = mcYears, timeStep = input$read_timeStep, + parallel = input$read_parallel + ) + + n_list <- length(list_data_all$antaresDataList) + 1 + list_data_all$antaresDataList[[n_list]] <- data + + # write params and links control + list_data_all$params[[n_list]] <- params + list_data_all$opts[[n_list]] <- opts() + if(!is.null(input$read_links)){ + list_data_all$have_links[n_list] <- TRUE + } else { + list_data_all$have_links[n_list] <- FALSE + } + have_areas <- is.null(input$read_areas) & is.null(input$read_links) & is.null(input$read_clusters) & + is.null(input$read_districts) | !is.null(input$read_areas) + if(have_areas){ + list_data_all$have_areas[n_list] <- TRUE + } else { + list_data_all$have_areas[n_list] <- FALSE + } + names(list_data_all$antaresDataList)[[n_list]] <- current_study_path() + } + + } else { + params <- list( + areas = input$read_areas, links = input$read_links, + clusters = input$read_clusters, districts = input$read_districts, + select = input$read_select + ) + + # a .h5 file, so return opts... + n_list <- length(list_data_all$antaresDataList) + 1 + list_data_all$antaresDataList[[n_list]] <- opts() + + # write params and links control + list_data_all$params[[n_list]] <- params + list_data_all$opts[[n_list]] <- opts() + if(!is.null(input$read_links)){ + list_data_all$have_links[n_list] <- TRUE + } else { + list_data_all$have_links[n_list] <- FALSE + } + have_areas <- is.null(input$read_areas) & is.null(input$read_links) & is.null(input$read_clusters) & + is.null(input$read_districts) | !is.null(input$read_areas) + if(have_areas){ + list_data_all$have_areas[n_list] <- TRUE + } else { + list_data_all$have_areas[n_list] <- FALSE + } + names(list_data_all$antaresDataList)[[n_list]] <- current_study_path() + } + } + }) + } +}) + +observe({ + if(input$import_data > 0){ + updateTabsetPanel(session, inputId = "tab_data", selected = "Analysis") + } +}) + +# control : have data +output$have_data <- reactive({ + length(list_data_all$antaresDataList) > 0 +}) +outputOptions(output, "have_data", suspendWhenHidden = FALSE) \ No newline at end of file diff --git a/inst/application/src/server/03_data_selection.R b/inst/application/src/server/03_data_selection.R new file mode 100644 index 0000000..33190c2 --- /dev/null +++ b/inst/application/src/server/03_data_selection.R @@ -0,0 +1,106 @@ +#------------------ +# gestion de la liste +#------------------ +output$info_list <- renderUI({ + list_data <- list_data_all$antaresDataList + if(length(list_data) > 0){ + isolate({ + # affichage du nom de l'etude + study <- lapply(1:length(list_data), function(i) { + study_name <- paste0("list_study_", i) + div( + h4(textOutput(study_name)), style = 'height:24px', align = "center") + }) + # checkbox de selection + check_list <- lapply(1:length(list_data), function(i) { + check_name <- paste0("list_study_check", i) + div( + checkboxInput(check_name, "Include study in analysis", value = TRUE), align = "center") + }) + # bouton pour afficher les parametres + params_list <- lapply(1:length(list_data), function(i) { + btn_name <- paste0("list_study_params", i) + div( + actionButton(btn_name, "View parameters"), align = "center") + }) + # bouton pour supprimer les donnees + rm_list <- lapply(1:length(list_data), function(i) { + btn_name <- paste0("list_study_rm", i) + div( + actionButton(btn_name, "Remove study"), align = "center") + }) + # format et retour + fluidRow( + column(3, do.call(tagList, study)), + column(3, do.call(tagList, params_list)), + column(3, do.call(tagList, check_list)), + column(3, do.call(tagList, rm_list)) + ) + }) + }else { + # element vide si pas de donnees + fluidRow() + } +}) + +# creation des outputs +# - titre de l'etude +# - print des parametres +observe({ + # lancement lors de la recuperation des donnees formatees + list_data_tmp <- list_data_all$antaresDataList + if(length(list_data_tmp) > 0){ + isolate({ + ctrl <- lapply(1:length(list_data_tmp), function(i) { + study_name <- paste0("list_study_", i) + study_params <- paste0("list_study_params", i) + output[[study_name]] <- renderText({ + paste0("Study : ", names(list_data_tmp)[i]) + }) + + output[[study_params]] <- renderPrint({ + str(list_data_all$params[[i]]) + }) + }) + }) + } +}) + +# observe locaux pour l'affichage des parametres +# et pour la suppression des etudes +for(j in 1:16){ + local({ + l_j <- j + observe({ + if(!is.null(input[[paste0("list_study_params", l_j)]])){ + if(input[[paste0("list_study_params", l_j)]] > 0){ + showModal(modalDialog( + easyClose = TRUE, + footer = NULL, + verbatimTextOutput(paste0("list_study_params", l_j)) + )) + } + } + }) + + observe({ + if(!is.null(input[[paste0("list_study_rm", l_j)]])){ + if(input[[paste0("list_study_rm", l_j)]] > 0){ + isolate({ + # print("remove") + # print(l_j) + # print(object_size(list_data_all$antaresDataList)) + # print(object_size(list_data_all$antaresDataList[l_j])) + # print(mem_change(list_data_all$antaresDataList[l_j] <- NULL)) + # print(object_size(list_data_all$antaresDataList)) + # print(object_size(list_data_all$antaresDataList[l_j])) + list_data_all$antaresDataList[l_j] <- NULL + list_data_all$params[l_j] <- NULL + gc(reset = TRUE) + + }) + } + } + }) + }) +} \ No newline at end of file diff --git a/inst/application/src/server/04_shared_input.R b/inst/application/src/server/04_shared_input.R new file mode 100644 index 0000000..28b450c --- /dev/null +++ b/inst/application/src/server/04_shared_input.R @@ -0,0 +1,77 @@ +input_data <- reactiveValues(data = .global_build_input_data(.global_shared_input), cpt = 0) + +observe({ + input_data$cpt + current_input_data <- input_data$data + for (ii in 1:nrow(current_input_data)){ + local({ + i <- ii + observe({ + current_value <- input[[current_input_data[i, input_id]]] + if(!is.null(current_value) & input$is_shared_input){ + isolate({ + current_input_data[i, last_update := as.character(Sys.time())] + if(isolate(current_input_data$update_call[i]) != ""){ + eval(parse(text = isolate(current_input_data$update_call[i]))) + isolate(current_input_data[i, update_call := ""]) + } + }) + } + }) + }) + } +}) + +observe({ + current_nav <- input[['nav-id']] + current_input_data <- isolate(input_data$data) + data_shared_input <- current_input_data[panel %in% current_nav] + if(nrow(data_shared_input) > 0 & input$is_shared_input){ + for(ii in 1:nrow(data_shared_input)){ + local({ + i <- ii + last_update_input <- current_input_data[!panel %in% current_nav & + input%in%data_shared_input[i, input] & + !is.na(last_update)][order(last_update, decreasing = TRUE)] + if(nrow(last_update_input) >= 1){ + if(data_shared_input[i, type] %in% "dateRangeInput"){ + if(!is.null(isolate({input[[data_shared_input[i, input_id]]]}))){ + updateDateRangeInput(session, data_shared_input[i, input_id], + start = isolate({input[[last_update_input[1, input_id]]][1]}), + end = isolate({input[[last_update_input[1, input_id]]][2]})) + } else { + expr <- paste0("updateDateRangeInput(session, '", data_shared_input[i, input_id], + "', start = '", isolate({input[[last_update_input[1, input_id]]][1]}), + "', end = '", isolate({input[[last_update_input[1, input_id]]][2]}), "')") + isolate({ + input_data$data[input_id %in% data_shared_input[i, input_id], update_call := expr] + }) + + } + + } else if(data_shared_input[i, type] %in% "selectInput"){ + if(!is.null(isolate({input[[data_shared_input[i, input_id]]]}))){ + updateSelectInput(session, data_shared_input[i, input_id], + selected = isolate({input[[last_update_input[1, input_id]]]})) + } else { + expr <- paste0("updateSelectInput(session, '", data_shared_input[i, input_id], + "', selected = '", isolate({input[[last_update_input[1, input_id]]]}), "')") + isolate({ + input_data$data[input_id %in% data_shared_input[i, input_id], update_call := expr] + }) + } + }else if(data_shared_input[i, type] %in% "checkboxInput"){ + if(!is.null(isolate({input[[data_shared_input[i, input_id]]]}))){ + updateCheckboxInput(session, data_shared_input[i, input_id], + value = isolate({input[[last_update_input[1, input_id]]]})) + } else { + expr <- paste0("updateCheckboxInput(session, '", data_shared_input[i, input_id], + "', value = ", isolate({input[[last_update_input[1, input_id]]]}), ")") + input_data$data[input_id %in% data_shared_input[i, input_id], update_call := expr] + } + } + } + }) + } + } +}) \ No newline at end of file diff --git a/inst/application/src/server/05_modules.R b/inst/application/src/server/05_modules.R new file mode 100644 index 0000000..0904045 --- /dev/null +++ b/inst/application/src/server/05_modules.R @@ -0,0 +1,174 @@ +observe({ + ind_keep_list_data <- ind_keep_list_data() + isolate({ + if(input$update_module > 0){ + if(is.null(ind_keep_list_data)){ + showModal(modalDialog( + easyClose = TRUE, + footer = NULL, + "No study selected" + )) + } else { + # plotts and prodStack + ind_areas <- ind_keep_list_data$ind_areas + if(length(ind_areas) > 0){ + # init / re-init module prodStack + id_prodStack <- paste0("prodStack_", round(runif(1, 1, 100000000))) + + # update shared input table + input_data$data[grepl("^prodStack", input_id), input_id := paste0(id_prodStack, "-shared_", input)] + + output[["prodStack_ui"]] <- renderUI({ + mwModuleUI(id = id_prodStack, height = "800px", fluidRow = TRUE) + }) + + .compare <- input$sel_compare_prodstack + if(input$sel_compare_mcyear){ + .compare <- unique(c(.compare, "mcYear")) + } + if(!is.null(.compare)){ + list_compare <- vector("list", length(.compare)) + names(list_compare) <- .compare + # set main with study names + if(length(ind_areas) != 1){ + list_compare$main <- names(list_data_all$antaresDataList[ind_areas]) + } + .compare <- list_compare + } else { + .compare = NULL + } + mod_prodStack <- prodStack(list_data_all$antaresDataList[ind_areas], xyCompare = "union", + h5requestFiltering = list_data_all$params[ind_areas], + unit = "GWh", interactive = TRUE, .updateBtn = TRUE, + .updateBtnInit = TRUE, compare = .compare, .runApp = FALSE) + + if("MWController" %in% class(modules$prodStack)){ + modules$prodStack$clear() + } + + modules$prodStack <- mwModule(id = id_prodStack, mod_prodStack) + + # init / re-init module plotts + id_ts <- paste0("plotts_", round(runif(1, 1, 100000000))) + + # update shared input table + input_data$data[grepl("^plotts", input_id), input_id := paste0(id_ts, "-shared_", input)] + + output[["plotts_ui"]] <- renderUI({ + mwModuleUI(id = id_ts, height = "800px", fluidRow = TRUE) + }) + + .compare <- input$sel_compare_tsPlot + if(input$sel_compare_mcyear){ + .compare <- unique(c(.compare, "mcYear")) + } + if(!is.null(.compare)){ + list_compare <- vector("list", length(.compare)) + names(list_compare) <- .compare + # set main with study names + if(length(ind_areas) != 1){ + list_compare$main <- names(list_data_all$antaresDataList[ind_areas]) + } + .compare <- list_compare + } else { + .compare = NULL + } + mod_plotts <- plot(list_data_all$antaresDataList[ind_areas], xyCompare = "union", + h5requestFiltering = list_data_all$params[ind_areas], + interactive = TRUE, .updateBtn = TRUE, + .updateBtnInit = TRUE, compare = .compare, .runApp = FALSE) + + if("MWController" %in% class(modules$plotts)){ + modules$plotts$clear() + } + + modules$plotts <- mwModule(id = id_ts, mod_plotts) + + list_data_controls$n_areas <- length(ind_areas) + list_data_controls$have_areas <- TRUE + } else { + list_data_controls$have_areas <- FALSE + } + + # exchange + ind_links <- ind_keep_list_data$ind_links + if(length(ind_links) > 0){ + # init / re-init module exchangesStack + id_exchangesStack <- paste0("exchangesStack_", round(runif(1, 1, 100000000))) + + # update shared input table + input_data$data[grepl("^exchangesStack", input_id), input_id := paste0(id_exchangesStack, "-shared_", input)] + + output[["exchangesStack_ui"]] <- renderUI({ + mwModuleUI(id = id_exchangesStack, height = "800px", fluidRow = TRUE) + }) + + .compare <- input$sel_compare_exchangesStack + if(input$sel_compare_mcyear){ + .compare <- unique(c(.compare, "mcYear")) + } + if(!is.null(.compare)){ + list_compare <- vector("list", length(.compare)) + names(list_compare) <- .compare + # set main with study names + if(length(ind_links) != 1){ + list_compare$main <- names(list_data_all$antaresDataList[ind_links]) + } + .compare <- list_compare + } else { + .compare = NULL + } + mod_exchangesStack <- exchangesStack(list_data_all$antaresDataList[ind_links], xyCompare = "union", + h5requestFiltering = list_data_all$params[ind_links], + interactive = TRUE, .updateBtn = TRUE, + .updateBtnInit = TRUE, compare = .compare, .runApp = FALSE) + + if("MWController" %in% class(modules$exchangesStack)){ + modules$exchangesStack$clear() + } + + modules$exchangesStack <- mwModule(id = id_exchangesStack, mod_exchangesStack) + + # save data and params + list_data_controls$n_links <- length(ind_links) + list_data_controls$have_links <- TRUE + } else { + list_data_controls$have_links <- FALSE + } + + if(!list_data_controls$have_areas & !list_data_controls$have_links){ + showModal(modalDialog( + easyClose = TRUE, + footer = NULL, + "No study with at least one area and/or link selected" + )) + } + } + } + + input_data$cpt <- isolate(input_data$cpt) +1 + }) +}) + +# control : have link in data +output$have_data_links <- reactive({ + list_data_controls$have_links +}) +outputOptions(output, "have_data_links", suspendWhenHidden = FALSE) + +# control : have areas in data +output$have_data_areas <- reactive({ + list_data_controls$have_areas +}) +outputOptions(output, "have_data_areas", suspendWhenHidden = FALSE) + +# change page +observe({ + if(input$update_module > 0){ + if(list_data_controls$have_areas & list_data_controls$n_areas >= 1){ + updateNavbarPage(session, inputId = "nav-id", selected = "prodStack") + } else if(list_data_controls$have_links & list_data_controls$n_links >= 1){ + updateNavbarPage(session, inputId = "nav-id", selected = "exchangesStack") + } + } +}) \ No newline at end of file diff --git a/inst/application/src/server/06_module_map.R b/inst/application/src/server/06_module_map.R new file mode 100644 index 0000000..21b61c5 --- /dev/null +++ b/inst/application/src/server/06_module_map.R @@ -0,0 +1,144 @@ +# list of opts for set layout +layout <- reactive({ + ind_keep_list_data <- ind_keep_list_data() + isolate({ + if(!is.null(ind_keep_list_data)){ + ind_map <- unique(sort(c(ind_keep_list_data$ind_areas, ind_keep_list_data$ind_links))) + if(length(ind_map) > 0){ + if(packageVersion("antaresRead") <= '2.0.0'){ + readLayout(opts = list_data_all$opts[ind_map][[1]]) + } else { + readLayout(opts = list_data_all$opts[ind_map]) + } + }else{ + NULL + } + } else { + NULL + } + }) +}) + +ml <- reactiveVal() +# module for set and save layout +ml_builder <- callModule(antaresViz:::changeCoordsServer, "ml", layout, + what = reactive("areas"), stopApp = FALSE) + +observe({ + ml(ml_builder()) +}) + +observe({ + ml_file <- input$import_layout + if (!is.null(ml_file)){ + tmp_ml <- try(readRDS(ml_file$datapath), silent = TRUE) + if("mapLayout" %in% class(tmp_ml)){ + ml(tmp_ml) + } else { + showModal(modalDialog( + title = "Invalid map layout file", + easyClose = TRUE, + footer = NULL, + "Must be a valid .RDS file (class 'mapLayout')" + )) + } + } +}) + +# control : have a not null layout, and so print map module ? +print_map <- reactiveValues(value = FALSE) + +observe({ + if(!is.null(ml())){ + print_map$value <- TRUE + } else { + print_map$value <- FALSE + } +}) + + +output$current_layout <- renderLeafletDragPoints({ + if(!is.null(ml())){ + plotMapLayout(ml()) + } +}) + +output$must_print_map <- reactive({ + print_map$value +}) + +outputOptions(output, "must_print_map", suspendWhenHidden = FALSE) + +observe({ + ml <- ml() + ind_keep_list_data <- ind_keep_list_data() + isolate({ + if(input$update_module > 0){ + if(!is.null(ind_keep_list_data)){ + ind_map <- unique(sort(c(ind_keep_list_data$ind_areas, ind_keep_list_data$ind_links))) + if(length(ind_map) > 0){ + if(!is.null(ml)){ + # init / re-init module plotMap + id_plotMap <- paste0("plotMap_", round(runif(1, 1, 100000000))) + + # update shared input table + input_data$data[grepl("^plotMap", input_id), input_id := paste0(id_plotMap, "-shared_", input)] + + output[["plotMap_ui"]] <- renderUI({ + mwModuleUI(id = id_plotMap, height = "800px", fluidRow = TRUE) + }) + + .compare <- input$sel_compare_plotMap + if(input$sel_compare_mcyear){ + .compare <- unique(c(.compare, "mcYear")) + } + if(!is.null(.compare)){ + list_compare <- vector("list", length(.compare)) + names(list_compare) <- .compare + # set main with study names + if(length(ind_map) != 1){ + list_compare$main <- names(list_data_all$antaresDataList[ind_map]) + } + .compare <- list_compare + } else { + .compare = NULL + } + + mod_plotMap <- plotMap(list_data_all$antaresDataList[ind_map], ml, + interactive = TRUE, .updateBtn = TRUE, + .updateBtnInit = TRUE, compare = .compare, + h5requestFiltering = list_data_all$params[ind_map], + xyCompare = "union", .runApp = FALSE) + + if("MWController" %in% class(modules$plotMap)){ + modules$plotMap$clear() + } + + modules$plotMap <- mwModule(id = id_plotMap, mod_plotMap) + # save data and params + list_data_controls$n_maps <- length(ind_map) + } + } + } + } + }) +}) + +# download layout +output$download_layout <- downloadHandler( + filename = function() { + paste('mapLayout-', Sys.Date(), '.RDS', sep='') + }, + content = function(con) { + saveRDS(ml(), file = con) + } +) + +# change page +observe({ + if(!is.null(input[['ml-done']])){ + if(input[['ml-done']] > 0){ + updateNavbarPage(session, inputId = "nav-id", selected = "Map") + } + } +}) \ No newline at end of file diff --git a/inst/application/src/tests/size_app.R b/inst/application/src/tests/size_app.R new file mode 100644 index 0000000..9363367 --- /dev/null +++ b/inst/application/src/tests/size_app.R @@ -0,0 +1,41 @@ +library(shiny) +library(manipulateWidget) +library(antaresViz) +library(pryr) + +ui <- fluidPage( + uiOutput("io"), + actionButton("goButton", "Go!") +) + + +server <- function(input, output, session) { + + tmp_prodstack <- NULL + + data <- reactiveValues(opts = setSimulationPath("C:\\Users\\Datastorm\\Desktop\\antares\\20171114-1533eco-base_30mc.h5")) + + output$io <- renderUI({ + mwModuleUI(paste0("mod2"), height = "800px") + }) + + observe({ + + print("object_size(session)") + print(object_size(session)) + input$goButton + isolate({ + prodStack <- prodStack(data$opts, xyCompare = "union", + unit = "GWh", interactive = TRUE, .updateBtn = TRUE, + .updateBtnInit = TRUE, .runApp = FALSE) + + if("MWController" %in% class(tmp_prodstack)){ + tmp_prodstack$clear() + } + tmp_prodstack <<- mwModule(id = paste0("mod2"), prodStack) + }) + }) + +} + +shinyApp(ui, server) \ No newline at end of file diff --git a/inst/application/src/ui/01_ui_import_data.R b/inst/application/src/ui/01_ui_import_data.R new file mode 100644 index 0000000..0578880 --- /dev/null +++ b/inst/application/src/ui/01_ui_import_data.R @@ -0,0 +1,41 @@ +tabPanel("Import Data", + h3("Antares study selection"), + fluidRow( + column(7, + directoryInput('directory', label = 'Select an antares study', + value = '') + ), + conditionalPanel(condition = "output.ctrl_is_antares_study | output.ctrl_is_antares_h5", + column(3, + selectInput("study_path", "Select a simulation", choices = NULL, selected = NULL) + ), + column(2, + div(br(), + actionButton("init_sim", "Set simulation", icon = icon("check-circle")), + align = "center" + ) + ) + ), + conditionalPanel(condition = "output.ctrl_is_antares_study === false & output.ctrl_is_antares_h5 === false", + column(5, + h3(textOutput("directory_message"), style = "color : red") + ) + ) + ), + + conditionalPanel(condition = "output.have_study", + hr(), + div(fluidRow( + column(6, + h3("ANTARES Simulation :", align = "right") + ), + column(6, + h3(textOutput("current_opts"), align = "left") + ) + )), + tabsetPanel(id = "args", + source("src/ui/02_ui_read_data.R", local = T)$value, + source("src/ui/03_ui_convert_h5.R", local = T)$value + ) + ) +) \ No newline at end of file diff --git a/inst/application/src/ui/02_ui_read_data.R b/inst/application/src/ui/02_ui_read_data.R new file mode 100644 index 0000000..20bdcee --- /dev/null +++ b/inst/application/src/ui/02_ui_read_data.R @@ -0,0 +1,92 @@ +tabPanel("Read data", + h3("readAntares parameters"), + fluidRow( + column(3, + selectInput("read_areas", "Areas :", choices = NULL, selected = NULL, multiple = TRUE) + ), + column(3, + selectInput("read_links", "Links :", choices = NULL, selected = NULL, multiple = TRUE) + ), + column(3, + selectInput("read_clusters", "Clusters : ", choices = NULL, selected = NULL, multiple = TRUE) + ), + column(3, + selectInput("read_districts", "Districts :", choices = NULL, selected = NULL, multiple = TRUE) + ) + ), + conditionalPanel(condition = "output.current_opts_h5 === false", + fluidRow( + column(3, + checkboxInput("read_misc", "misc", FALSE), + checkboxInput("read_reserve", "reserve", FALSE) + ), + column(3, + checkboxInput("read_thermalAvailabilities", "thermalAvailabilities", FALSE), + checkboxInput("read_linkCapacity", "linkCapacity", FALSE) + ), + column(3, + checkboxInput("read_hydroStorage", "hydroStorage", FALSE), + checkboxInput("read_mustRun", "mustRun", FALSE) + ), + column(3, + checkboxInput("read_hydroStorageMaxPower", "hydroStorageMaxPower", FALSE), + checkboxInput("read_thermalModulation", "thermalModulation", FALSE) + ) + ), + fluidRow( + column(3, + selectInput("read_timeStep", "timeStep :", choices = c("hourly", "daily", "weekly", + "monthly", "annual")) + ), + column(3, + radioButtons("read_type_mcYears", "mcYears :", + c("synthetic", "all", "custom"), inline = TRUE) + ), + conditionalPanel(condition = "input.read_type_mcYears === 'custom'", + column(3, + selectInput("read_mcYears", "Choose mcYears :", choices = NULL, selected = NULL, multiple = TRUE) + ) + ) + # ,column(3, + # checkboxInput("read_parallel", "parallel", FALSE) + # ) + ) + ), + fluidRow( + column(12, + selectInput("read_select", "Select :", choices = NULL, selected = NULL, + width = "100%", multiple = TRUE) + ) + ), + conditionalPanel(condition = "output.current_opts_h5 === false", + fluidRow( + column(3, + h4("removeVirtualAreas :") + ), + column(3, + checkboxInput("rmva_ctrl", "enabled", FALSE) + ) + ), + conditionalPanel(condition = "input.rmva_ctrl", + fluidRow( + column(3, + selectInput("rmva_storageFlexibility", "storageFlexibility :", choices = NULL, selected = NULL, multiple = TRUE) + ), + column(3, + selectInput("rmva_production", "production :", choices = NULL, selected = NULL, multiple = TRUE) + ), + + column(3, + br(), + checkboxInput("rmva_reassignCosts", "reassignCosts", FALSE) + ), + + column(3, + br(), + checkboxInput("rmva_newCols", "newCols", FALSE) + ) + ) + ) + ), + div(actionButton("import_data", "Validate & import data", icon = icon("upload")), align = "center") +) \ No newline at end of file diff --git a/inst/application/src/ui/04_ui_analysis.R b/inst/application/src/ui/04_ui_analysis.R new file mode 100644 index 0000000..69341e0 --- /dev/null +++ b/inst/application/src/ui/04_ui_analysis.R @@ -0,0 +1,31 @@ +tabPanel("Analysis", + conditionalPanel(condition = "output.have_data === true", + div(h3("Analysis parameters"), align = "center"), + h3("Studies :"), + uiOutput("info_list"), + h3("Compare :"), + fluidRow( + + column(3, + selectInput("sel_compare_prodstack", "prodStack :", choices = .global_compare_prodstack, selected = NULL, multiple = TRUE) + ), + column(3, + selectInput("sel_compare_exchangesStack", "exchangesStack :", choices = .global_compare_exchangesStack, selected = NULL, multiple = TRUE) + ), + column(3, + selectInput("sel_compare_tsPlot", "tsPlot : ", choices = .global_compare_tsPlot, selected = NULL, multiple = TRUE) + ), + column(3, + selectInput("sel_compare_plotMap", "plotMap :", choices = .global_compare_plotMap, selected = NULL, multiple = TRUE) + ) + ), + + checkboxInput("sel_compare_mcyear", "mcYear on all modules ?", FALSE), + + br(), + div(actionButton("update_module", "Launch Analysis", icon = icon("upload")), align = "center") + ), + conditionalPanel(condition = "output.have_data === false", + h3("No data imported from 'Import Data' panel", style = "color : red") + ) +) \ No newline at end of file diff --git a/inst/application/src/ui/05_ui_prodstack.R b/inst/application/src/ui/05_ui_prodstack.R new file mode 100644 index 0000000..10a7ee4 --- /dev/null +++ b/inst/application/src/ui/05_ui_prodstack.R @@ -0,0 +1,17 @@ +tabPanel("prodStack", + fluidRow( + column(12, + conditionalPanel(condition = "output.have_data", + conditionalPanel(condition = "output.have_data_areas", + uiOutput("prodStack_ui") + ), + conditionalPanel(condition = "output.have_data_areas === false", + h3("No areas imported") + ) + ), + conditionalPanel(condition = "output.have_data === false", + h3("No data imported") + ) + ) + ) +) \ No newline at end of file diff --git a/inst/application/src/ui/06_ui_exchange.R b/inst/application/src/ui/06_ui_exchange.R new file mode 100644 index 0000000..1154103 --- /dev/null +++ b/inst/application/src/ui/06_ui_exchange.R @@ -0,0 +1,17 @@ +tabPanel("exchangesStack", + fluidRow( + column(12, + conditionalPanel(condition = "output.have_data", + conditionalPanel(condition = "output.have_data_links", + uiOutput("exchangesStack_ui") + ), + conditionalPanel(condition = "output.have_data_links === false", + h3("No links imported") + ) + ), + conditionalPanel(condition = "output.have_data === false", + h3("No data imported") + ) + ) + ) +) \ No newline at end of file diff --git a/inst/application/src/ui/07_ui_tsplot.R b/inst/application/src/ui/07_ui_tsplot.R new file mode 100644 index 0000000..a3948dc --- /dev/null +++ b/inst/application/src/ui/07_ui_tsplot.R @@ -0,0 +1,17 @@ +tabPanel("tsPlot", + fluidRow( + column(12, + conditionalPanel(condition = "output.have_data", + conditionalPanel(condition = "output.have_data_areas", + uiOutput("plotts_ui") + ), + conditionalPanel(condition = "output.have_data_areas === false", + h3("No areas imported") + ) + ), + conditionalPanel(condition = "output.have_data === false", + h3("No data imported") + ) + ) + ) +) \ No newline at end of file diff --git a/inst/application/src/ui/09_ui_params.R b/inst/application/src/ui/09_ui_params.R new file mode 100644 index 0000000..07d576d --- /dev/null +++ b/inst/application/src/ui/09_ui_params.R @@ -0,0 +1,20 @@ +tabPanel("Parameters", + fluidRow( + column(2, checkboxInput("is_shared_input", label = "Share inputs between modules ?", value = TRUE)), + column(2, h4("readAntares RAM limit (in Go) : ")), + column(3, div(numericInput("ram_limit", label = NULL, + min = 1, max = 10, value = { + if(!is.null(getOption("maxSizeLoad"))){ + getOption("maxSizeLoad") + } else {10} + }), align = "center")), + column(2, h4("antaresViz data module (in Mb) : ")), + column(3, div(numericInput("data_module", label = NULL, + min = 1, max = 10, value = { + if(!is.null(getOption("antaresVizSizeGraph"))){ + getOption("antaresVizSizeGraph") + } else {200} + }), align = "center")) + + ) +) \ No newline at end of file diff --git a/inst/application/src/ui/10_ui_help.R b/inst/application/src/ui/10_ui_help.R new file mode 100644 index 0000000..c037a67 --- /dev/null +++ b/inst/application/src/ui/10_ui_help.R @@ -0,0 +1,26 @@ +tabPanel("Help", + fluidRow( + column(width = 12, + HTML(text = "For any questions, please contact RTE-ANTARES-RPACKAGE Team .

"), + tabsetPanel( + tabPanel("R function readAntares", + fluidRow( + column(12, includeHTML("www/readAntares.html")) + ) + ), + tabPanel("R function removeVirtualAreas", + fluidRow( + column(12, includeHTML("www/removeVirtualAreas.html")) + ) + ), + tabPanel("R function writeAntaresH5", + fluidRow( + column(12, includeHTML("www/writeAntaresH5.html")) + ) + ) + ) + + ) + + ) +) \ No newline at end of file diff --git a/inst/application/ui.R b/inst/application/ui.R new file mode 100644 index 0000000..6bd73aa --- /dev/null +++ b/inst/application/ui.R @@ -0,0 +1,38 @@ +# Define UI for antaresViz app +navbarPage(title = "antaresViz", id = "nav-id", inverse= TRUE, collapsible = TRUE, position = "fixed-top", + header = fluidRow( + column(12, + br(), br(), br(), + singleton(tags$script(src = 'events.js')), + div(id = "import_busy", tags$img(src= "spinner.gif", height = 100, + style = "position: fixed;top: 50%;z-index:10;left: 48%;")) + ) + ), windowTitle = "antaresViz", + tabPanel("Data", + fluidRow( + column(12, + tabsetPanel(id = "tab_data", + source("src/ui/01_ui_import_data.R", local = T)$value, + source("src/ui/04_ui_analysis.R", local = T)$value + ) + ) + ) + ), + + source("src/ui/05_ui_prodstack.R", local = T)$value, + + source("src/ui/06_ui_exchange.R", local = T)$value, + + source("src/ui/07_ui_tsplot.R", local = T)$value, + + source("src/ui/08_ui_map.R", local = T)$value, + + source("src/ui/09_ui_params.R", local = T)$value, + + source("src/ui/10_ui_help.R", local = T)$value, + + footer = div(hr(), actionButton("quit", "Quit application", icon = icon("sign-out")), align = "center") +) + + + diff --git a/inst/application/www/events.js b/inst/application/www/events.js new file mode 100644 index 0000000..dfeb11f --- /dev/null +++ b/inst/application/www/events.js @@ -0,0 +1,13 @@ +$(function() { + $(document).on({ + + 'shiny:busy': function(event) { + $('#import_busy').css("visibility", "visible"); + }, + + 'shiny:idle': function(event) { + $('#import_busy').css("visibility", "hidden"); + } + }); + +}); \ No newline at end of file diff --git a/inst/application/www/js/directory_input_binding.js b/inst/application/www/js/directory_input_binding.js new file mode 100644 index 0000000..f4decc7 --- /dev/null +++ b/inst/application/www/js/directory_input_binding.js @@ -0,0 +1,57 @@ +(function() { +/** + * Shiny Registration + */ + +var directoryInputBinding = new Shiny.InputBinding(); +$.extend(directoryInputBinding, { + find: function(scope) { + return( $(scope).find(".directory-input") ); + }, + initialize: function(el) { + // called when document is ready using initial values defined in ui.R + // documented in input_binding.js but not in docs (articles) + }, + getId: function(el) { + return($(el).attr('id')); + }, + getValue: function(el) { + return($(el).data('val') || 0); + }, + setValue: function(el, value) { + $(el).data('val', value); + }, + receiveMessage: function(el, data) { + // This is used for receiving messages that tell the input object to do + // things, such as setting values (including min, max, and others). + // documented in input_binding.js but not in docs (articles) + var $widget = $(el).parentsUntil('.directory-input-container').parent(); + var $path = $widget.find('input.directory-input-chosen-dir'); + + console.log('message received: ' + data.chosen_dir); + + if (data.chosen_dir) { + $path.val(data.chosen_dir); + $path.trigger('change'); + } + }, + subscribe: function(el, callback) { + $(el).on("click.directoryInputBinding", function(e) { + var $el = $(this); + var val = $el.data('val') || 0; + $el.data('val', val + 1); + + console.log('in subscribe: click'); + callback(); + }); + }, + unsubscribe: function(el) { + $(el).off(".directoryInputBinding"); + } +}); + +Shiny.inputBindings + .register(directoryInputBinding, "oddhypothesis.directoryInputBinding"); + + +})(); diff --git a/inst/application/www/readAntares.html b/inst/application/www/readAntares.html new file mode 100644 index 0000000..d7fc0ea --- /dev/null +++ b/inst/application/www/readAntares.html @@ -0,0 +1,274 @@ +R: Read the data of an Antares simulation + + + + +
readAntaresR Documentation
+ +

Read the data of an Antares simulation

+ +

Description

+ +

readAntares is a swiss-army-knife function used to read almost every +possible time series of an antares Project at any desired time resolution +(hourly, daily, weekly, monthly or annual). +

+

It was first designed to read +output time series, but it can also read input time series. The input time +series are processed by the function to fit the query of the user (timeStep, +synthetic results or Monte-Carlo simulation, etc.). The few data that are not +read by readAntares can generally by read with other functions of the +package starting with "read" (readClusterDesc, +readLayout, readBindingConstraints) +

+ + +

Usage

+ +
+readAntares(areas = NULL, links = NULL, clusters = NULL,
+  districts = NULL, misc = FALSE, thermalAvailabilities = FALSE,
+  hydroStorage = FALSE, hydroStorageMaxPower = FALSE, reserve = FALSE,
+  linkCapacity = FALSE, mustRun = FALSE, thermalModulation = FALSE,
+  select = NULL, mcYears = NULL, timeStep = c("hourly", "daily", "weekly",
+  "monthly", "annual"), opts = simOptions(), parallel = FALSE,
+  simplify = TRUE, showProgress = TRUE)
+
+ + +

Arguments

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
areas +

Vector containing the names of the areas to import. If +NULL no area is imported. The special value "all" tells the +function to import all areas. By default, the value is "all" when no other argument is enter and "NULL" when other arguments are enter.

+
links +

Vector containing the name of links to import. If NULL no +area is imported. The special value "all" tells the function to +import all areas. Use function getLinks to import all links +connected to some areas.

+
clusters +

Vector containing the name of the areas for which you want to +import results at cluster level. If NULL no cluster is imported. The +special value "all" tells the function to import clusters from all +areas.

+
districts +

Vector containing the names of the districts to import. If NULL, +no district is imported. The special value "all" tells the function to import all +districts.

+
misc +

Vector containing the name of the areas for which you want to +import misc.

+
thermalAvailabilities +

Should thermal availabilities of clusters be imported ? If TRUE, the column +"thermalAvailability" is added to the result and a new column "availableUnits" +containing the number of available units in a cluster is created.If synthesis is set to TRUE then +"availableUnits" contain the mean of avaible units on all MC Years.

+
hydroStorage +

Should hydro storage be imported ?

+
hydroStorageMaxPower +

Should hydro storage maximum power be imported ?

+
reserve +

Should reserve be imported ?

+
linkCapacity +

Should link capacities be imported ?

+
mustRun +

Should must run productions be added to the result? If TRUE, +then four columns are added: mustRun contains the production of +clusters that are in complete must run mode; mustRunPartial +contains the partial must run production of clusters; mustRunTotal +is the sum of the two previous columns. Finally thermalPmin is +similar to mustRunTotal except it also takes into account the production +induced by the minimum stable power of the units of a cluster. More +precisely, for a given cluster and a given time step, it is equal to +min(NODU x min.stable.power, mustRunTotal).

+
thermalModulation +

Should thermal modulation time series be imported ? If TRUE, the +columns "marginalCostModulation", "marketBidModulation", "capacityModulation" +and "minGenModulation" are added to the cluster data.

+
select +

Character vector containing the name of the columns to import. If this +argument is NULL, all variables are imported. Special names +"allAreas" and "allLinks" indicate to the function to import +all variables for areas or for links. Since version 1.0, values "misc", +"thermalAvailabilities", "hydroStorage", "hydroStorageMaxPower", "reserve", +"linkCapacity", "mustRun", "thermalModulation" are also accepted and can +replace the corresponding arguments. The list of available variables can be +seen with the command simOptions()$variables. Id variables like +area, link or timeId are automatically imported.

+
mcYears +

Index of the Monte-Carlo years to import. If NULL, synthetic results +are read, else the specified Monte-Carlo simulations are imported. The +special value all tells the function to import all Monte-Carlo +simulations.

+
timeStep +

Resolution of the data to import: hourly (default), daily, +weekly, monthly or annual.

+
opts +

list of simulation parameters returned by the function +setSimulationPath

+
parallel +

Should the importation be parallelized ? (See details)

+
simplify +

If TRUE and only one type of output is imported then a +data.table is returned. If FALSE, the result will always be a list of class +"antaresData".

+
showProgress +

If TRUE the function displays information about the progress of the +importation.

+
+ + +

Details

+ +

If parameters areas, links, clusters and districts +are all NULL, readAntares will read output for all areas. +By default the function reads synthetic results if they are available. +

+

readAntares is able to read input time series, but when they are not +stored in output, these time series may have changed since a simulation has +been run. In such a case the function will remind you this danger with a +warning. +

+

When individual Monte-Carlo simulations are read, the function may crash +because of insufficient memory. In such a case, it is necessary to reduce +size of the output. Different strategies are available depending on your +objective: +

+ + + + + +

Value

+ +

If simplify = TRUE and only one type of output is imported +then the result is a data.table. +

+

Else an object of class "antaresDataList" is returned. It is a list of +data.tables, each element representing one type of element (areas, links, +clusters) +

+ + +

Parallelization

+ +

If you import several elements of the same type (areas, links, clusters), you +can use parallelized importation to improve performance. Setting the +parameter parallel = TRUE is not enough to parallelize the +importation, you also have to install the package +foreach +and a package that provides a parallel backend (for instance the package +doParallel). +

+

Before running the function with argument parallel=TRUE, you need to +register your parallel backend. For instance, if you use package "doParallel" +you need to use the function registerDoParallel once per +session. +

+ + +

See Also

+ +

setSimulationPath, getAreas, +getLinks, getDistricts +

+ + +

Examples

+ +
+## Not run: 
+# Import areas and links separately
+
+areas <- readAntares() # equivalent to readAntares(areas="all")
+links <- readAntares(links="all")
+
+# Import areas and links at same time
+
+output <- readAntares(areas = "all", links = "all")
+
+# Add input time series to the object returned by the function
+areas <- readAntares(areas = "all", misc = TRUE, reserve = TRUE)
+
+# Get all output for one area
+
+myArea <- sample(simOptions()$areaList, 1)
+myArea
+
+myAreaOutput <- readAntares(area = myArea,
+                            links = getLinks(myArea, regexpSelect=FALSE),
+                            clusters = myArea)
+
+# Or equivalently:
+myAreaOutput <- readAntaresAreas(myArea)
+
+# Use parameter "select" to read only some columns.
+
+areas <- readAntares(select = c("LOAD", "OV. COST"))
+
+# Aliases can be used to select frequent groups of columns. use showAliases()
+# to view a list of available aliases
+
+areas <- readAntares(select="economy")
+
+
+## End(Not run)
+
+ + + diff --git a/inst/application/www/removeVirtualAreas.html b/inst/application/www/removeVirtualAreas.html new file mode 100644 index 0000000..842c7fb --- /dev/null +++ b/inst/application/www/removeVirtualAreas.html @@ -0,0 +1,178 @@ +R: Remove virtual areas + + + + +
removeVirtualAreasR Documentation
+ +

Remove virtual areas

+ +

Description

+ +

This function removes virtual areas from an antaresDataList object and +corrects the data for the real areas. The antaresDataList object +should contain area and link data to function correctly. +

+ + +

Usage

+ +
+removeVirtualAreas(x, storageFlexibility = NULL, production = NULL,
+  reassignCosts = FALSE, newCols = TRUE)
+
+ + +

Arguments

+ + + + + + + + + + + + +
x +

An object of class antaresDataList with at least components +areas and links.

+
storageFlexibility +

A vector containing the names of the virtual +storage/flexibility areas.

+
production +

A vector containing the names of the virtual production +areas.

+
reassignCosts +

If TRUE, the production costs of the virtual areas are +reallocated to the real areas they are connected to. If the virtual areas +are connected to a virtual hub, their costs are first reallocated to the +hub and then the costs of the hub are reallocated to the real areas.

+
newCols +

If TRUE, new columns containing the production of the virtual +areas are added. If FALSE their production is added to the production of +the real areas they are connected to.

+
+ + +

Details

+ +

Two types of virtual areas have been defined corresponding to different types +of modeling in Antares and different types of post-treatment to do: +

+ + + +

removeVirtualAreas performs different corrections: +

+ + + +

The functions makes a few assumptions about the network. if they are +violated it will not act correctly: +

+ + + + + +

Value

+ +

An antaresDataList object in which virtual areas have been removed and +data of the real has been corrected. See details for an explanation of the +corrections. +

+ + +

Examples

+ +
+## Not run: 
+
+# Assume we have a network with two virtual areas acting as pump storage and
+# an area representing offshore production
+#
+#  offshore
+#     |
+# real area - psp in
+#           \
+#             psp out
+#
+
+data <- readAntares(areas="all", links="all")
+
+# Remove pump storage virtual areas
+
+correctedData <- removeVirtualAreas(data, 
+                                    storageFlexibility = c("psp in", "psp out"),
+                                    production = "offshore")
+
+## End(Not run)
+
+
+ + + diff --git a/inst/application/www/spinner.gif b/inst/application/www/spinner.gif new file mode 100644 index 0000000..d79561d Binary files /dev/null and b/inst/application/www/spinner.gif differ diff --git a/inst/application/www/writeAntaresH5.html b/inst/application/www/writeAntaresH5.html new file mode 100644 index 0000000..addf33a --- /dev/null +++ b/inst/application/www/writeAntaresH5.html @@ -0,0 +1,161 @@ +R: Convert antares output to h5 file + + + + +
writeAntaresH5R Documentation
+ +

Convert antares output to h5 file

+ +

Description

+ +

Convert antares output to h5 file +

+ + +

Usage

+ +
+writeAntaresH5(path = getwd(), timeSteps = c("hourly", "daily", "weekly",
+  "monthly", "annual"), opts = simOptions(), writeMcAll = TRUE,
+  compress = 1, misc = FALSE, thermalAvailabilities = FALSE,
+  hydroStorage = FALSE, hydroStorageMaxPower = FALSE, reserve = FALSE,
+  linkCapacity = FALSE, mustRun = FALSE, thermalModulation = FALSE,
+  allData = FALSE, writeAllSimulations = FALSE, nbCores = 4,
+  removeVirtualAreas = FALSE, storageFlexibility = NULL,
+  production = NULL, reassignCosts = FALSE, newCols = TRUE,
+  overwrite = FALSE, supressMessages = FALSE)
+
+ + +

Arguments

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
path +

character folder where h5 file will be write (default getwd())

+
timeSteps +

character timeSteps

+
opts +

list of simulation parameters returned by the function setSimulationPath. Defaut to antaresRead::simOptions()

+
writeMcAll +

boolean write mc-all

+
compress +

numeric compress level

+
misc +

boolean see readAntares

+
thermalAvailabilities +

boolean see readAntares

+
hydroStorage +

boolean see readAntares

+
hydroStorageMaxPower +

boolean see readAntares

+
reserve +

boolean see readAntares

+
linkCapacity +

boolean see readAntares

+
mustRun +

boolean see readAntares

+
thermalModulation +

boolean see readAntares

+
allData +

boolean add all data with a single call (writeMcAll, misc, thermalAvailabilities, hydroStorage, hydroStorageMaxPower +reserve, linkCapacity, mustRun, thermalModulation).

+
writeAllSimulations +

boolean, write all simulations of your antares study.

+
nbCores +

numeric, number of cores to use, only used if writeAllSimulations is TRUE

+
removeVirtualAreas +

boolean, remove virtual areas, see removeVirtualAreas

+
storageFlexibility +

character, see removeVirtualAreas

+
production +

character, see removeVirtualAreas

+
reassignCosts +

boolean, see removeVirtualAreas

+
newCols +

boolean, see removeVirtualAreas

+
overwrite +

boolean, overwrite old file

+
supressMessages +

boolean, supress messages from readAntares and removeVirtualAreas

+
+ + +

Examples

+ +
+
+## Not run: 
+# Write simulation one by one
+setSimulationPath("C:/Users/MyUser/Mystudy", 1)
+writeAntaresH5()
+
+# Write all simulations
+setSimulationPath("C:/Users/MyUser/Mystudy")
+writeAntaresH5(writeAllSimulations = TRUE)
+
+# Choose timestep to write
+setSimulationPath("C:/Users/MyUser/Mystudy", 1)
+writeAntaresH5(timeSteps = "hourly")
+
+# Write with additionnal information
+writeAntaresH5(timeSteps = "hourly",
+   misc = TRUE, thermalAvailabilities = TRUE,
+   hydroStorage = TRUE, hydroStorageMaxPower = TRUE, reserve = TRUE,
+   linkCapacity = TRUE, mustRun = TRUE, thermalModulation = TRUE)
+
+# Write all data with a shorcut 
+writeAntaresH5(allData = TRUE)
+
+
+## End(Not run)
+
+ + + diff --git a/inst/color.csv b/inst/color.csv new file mode 100644 index 0000000..b2dcc13 --- /dev/null +++ b/inst/color.csv @@ -0,0 +1,21 @@ +red;green;blue;Column +17;71;185;PSP +120;136;194;mustRunTotal +120;236;194;mustRunPartial +220;236;94;mustRun +22;106;87;MISC. NDG +116;205;185;WIND +242;116;6;SOLAR +245;179;0;NUCLEAR +243;10;10;GAS +172;140;53;COAL +135;86;39;LOAD +39;114;178;H. STOR +180;130;43;LIGNITE +131;86;162;OIL +127;84;156;MIX. FUEL +173;255;47;MISC. DTG +61;96;125;H. ROR +84;151;208;H. STOR +101;180;197;netLoad +1;1;1;AVL DTG diff --git a/inst/htmlwidgets/leafletDragPoints.js b/inst/htmlwidgets/leafletDragPoints.js index 8e6041a..b3de06f 100644 --- a/inst/htmlwidgets/leafletDragPoints.js +++ b/inst/htmlwidgets/leafletDragPoints.js @@ -14,14 +14,22 @@ HTMLWidgets.widget({ ).addTo(map); var points = []; + var mapLayer; + var markersLayer = []; + + function clear_polyline() { + map.removeLayer( linesFeatureLayer ); + } // Function that updates shiny input function updateShinyInput() { var coords = points.map(function(p) { return p.marker.getLatLng(); }); - Shiny.onInputChange(el.id + "_coords", coords); - Shiny.onInputChange(el.id + "_mapcenter", map.getCenter()); + if(HTMLWidgets.shinyMode){ + Shiny.onInputChange(el.id + "_coords", coords); + Shiny.onInputChange(el.id + "_mapcenter", map.getCenter()); + } } map.on("moveend", updateShinyInput); @@ -32,37 +40,66 @@ HTMLWidgets.widget({ return { renderValue: function(x) { + if(x.init){ + for(var i=0;i + %\VignetteIndexEntry{Vignette Title} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + + + +![](antareslogo.png) + +This package works along with RTE's adequacy software ANTARES : https://antares.rte-france.com/ + +`antaresViz` is a package which proposes relevant graphs and maps to vizualize the results of an ANTARES study, with numerous settings and possible customizations. + + + +## Where everything starts + + +```{r loadPackage, message = FALSE, warning=FALSE} +library(antaresViz) +``` + + +The data from an ANTARES study can be imported and easily manipulated using the [antaresRead](https://github.com/rte-antares-rpackage/antaresRead) package. + +The examples presented below have been build on a fictionnal study whose output have been loaded with antaresRead. They contains different types of elements : + + * outputs with an annual and an hourly time step, + * synthetic outputs (averaged on several Monte-Carlo years) and detailled outputs (given year by year), + * outputs for areas, links, clusters and districts. + + +```{r loadData, message = FALSE} +load("data_for_antaresViz_vignette_extralight.Rdata") +``` + +The aim of this vignette is to give a quick overview of the possibilities offered by the package antaresViz. The data with which the following graphs have been plotted are fictionnal. + +## The simple power of the `plot` function + +The `plot()` function, used with an antaresDataList object (i.e. an object returned by the `antaresRead::readAntares()` function) offers different possible vizualisations. + +Moreover, this function is __really easy to use__. It opens a shiny interface which let the user decide : + +* Which type of __element__ he wants to study : areas, links or disctricts. +* Which __variable__ he wants to analyze. +* With which type of __graph__ : barplot, time series, probability density function, heatmap, etc. +* For which area(s), link(s), or district(s). +* And during which __time period__. + + +```r +plot(data_hourly_synthesis) +``` + +![](plot_resized.gif) + + +Note that all the interface manipulation can also be set directly in the arguments of the `plot` function. Some examples of the multiple graphs that can be returned by this function are given below. + +###### Barplot of Loss of Load Duration (LOLD) for several districts of the study + +```{r barplot, eval = FALSE} +plot(data_annual_synthesis, table = "districts" ,variable = "LOLD", type = "barplot", elements = c("00_a", "00_b", "00_c", "00_d", "00_e", "00_f", "00_g", "00_h", "00_i"), interactive = FALSE, width = "100%", height = 400) +``` + + +###### Time series of the load in an area with average value and 95% confidence interval. + +```{r ts, eval=FALSE} +plot(data_hourly_allmc, table = "areas" ,variable = "LOAD", type = "ts", elements = "23_b", confInt = 0.95, dateRange = c("2018-01-08", "2018-01-14"), width = "100%", height = 400, interactive = FALSE) +``` + + +###### Probability density function of the wind power generation in two areas +```{r density, eval=FALSE} +plot(data_hourly_synthesis, table = "areas" ,variable = "WIND", type = "density", elements = c("01_a", "02_a"), interactive = FALSE, width = "100%", height = 400) +``` + + +###### Heatmap of the congestion probability of one interconnection + +```{r heatmap, eval=FALSE} +plot(data_hourly_synthesis_1year, table = "links", variable = "CONG. PROB +", type = "heatmap", elements = "25_c - 26_d", interactive = FALSE, width = "100%", height = 400, main = "Congestion probability") +``` + + +Note that the `plot()` function also contains a `compare` argument which allows comparisons between : + +* different variables +* different areas/links/district +* different studies + + +## When the production meets the demand + +The `prodStack` function builds a graph which contains the time series of demand in one area (or the sum of the demand of a set of areas) along with the generation of this area (or set of areas), divided between the different fuel types (e.g. nuclear, gas, wind, etc). + + +```r +prodStack(data_hourly_synthesis) +``` + +Once again, this function is easy to use and opens a shiny interface which let the user manipulate the selected areas and time range. Some settings can also be passed to the function through its (optionnal) arguments. + +```{r prodStack, eval = FALSE} +prodStack(data_hourly_synthesis, stack = "eco2mix", areas = "37_h", dateRange = c("2018-01-08", "2018-01-21"), main = "Production stack", unit = "GWh", interactive = FALSE, width = "100%", height = 500) +``` + +The graphical template used by default is the one of the RTE's application [eco2mix](http://www.rte-france.com/fr/eco2mix/eco2mix-mix-energetique). This template can though be redefined completely by the user with the function `setProdStackAlias()`. + +The `exchangesStack()` function proposes similar graphs with a superposition of all the imports and exports of an area. + +```{r exchangeStack, eval = FALSE} +exchangesStack(data_hourly_synthesis, area = "37_h", dateRange = c("2018-01-08", "2018-01-21"), main = "Import/Export of area 37_h", unit = "GWh", interactive = FALSE, width = "100%", height = 500) +``` + +## Everything looks better on a map + +Last but not least, `antaresViz` proposes several function to vizualise the results of a study on a map. + +To do so, the first function to use is `mapLayout()`. This function launches an interactive application that let the user place areas of the ANTARES study on a map. + + +```r +antares_layout <- antaresRead::readLayout(opts = antaresRead::setSimulationPath(study_path)) +map_layout <- mapLayout(layout = antares_layout) +``` + +![](maplyout_resized.gif) + +(Once again : the study presented here is fictionnal !) + + +The function `plotMap()` then generates an interactive map that let the user visually explore the results of an Antares simulation. By default the function starts a Shiny gadget that let the user choose : + + * Which __variable__ to represent + * With which __type of vizualisation__ + - areas : color, size, popup, label + - links : color, width of the link, popup + * For which __time step__ or __date range__ + + +```r +plotMap(data_hourly_synthesis, map_layout) +``` + +Some examples of results returned by the `plotMap()` function are depicted below. + + + +###### C02 emissions + +This first map depicts the annual CO2 emissions of all the areas of the ANTARES study. + + +```{r plotmap_co2, eval = FALSE} +plotMap(data_annual_filtered, map_layout, showLabels = TRUE, sizeAreaVar = "CO2 EMIS.", interactive = FALSE, labelAreaVar = "CO2 EMIS.", colAreaVar = "CO2 EMIS.", type = "avg", options = plotMapOptions(areaDefaultSize = 30, labelMaxSize = 8, labelMinSize = 14, areaColorScaleOpts = colorScaleOptions(zeroCol = "white", posCol = "red2")), width = "100%", height = 600) +``` + + +###### Average balance and flows in the system + +This map illustrates the annual balance (MWh exported if positive - or imported if negative - during an hour) of each area and the annual flows of each link. + +```{r plotmap_flows, eval = FALSE} +plotMap(data_annual_synthesis, map_layout, showLabels = TRUE, colAreaVar = "BALANCE", interactive = FALSE, labelAreaVar = "BALANCE", sizeLinkVar = "FLOW LIN.", type = "avg", options = plotMapOptions(areaDefaultSize = 30, labelMaxSize = 10, labelMinSize = 8, areaColorScaleOpts = colorScaleOptions(negCol = "tomato3", zeroCol = "white", posCol = "blue3")), width = "100%", height = 600) +``` + + +###### Energy mixes + +The proportion of each energy type in the annual production of each area is illustrated on this next map. The actual generated energies (in MWh) can be known by clicking on the pie charts. + +```{r plotmap_mix, eval = FALSE} +data_annual_synthesis$areas <- data_annual_synthesis$areas[, `:=`(THERMAL = NUCLEAR + LIGNITE + COAL + GAS + OIL + `MIX. FUEL` + `MISC. DTG`, HYDRO =`H. ROR` + `H. STOR`)] + +plotMap(data_annual_synthesis, map_layout, interactive = FALSE, sizeAreaVars = c("HYDRO", "SOLAR", "WIND", "THERMAL"), popupAreaVars = c("HYDRO", "SOLAR", "WIND", "THERMAL"),areaChartType = "pie", type = "avg", options = plotMapOptions(areaDefaultSize = 25), width = "100%", height = 600) +``` + + + +## Let's get started + +The `antaresViz` package is available on the CRAN and can be installed with : +```r +install.packages("antaresViz") +``` + diff --git a/vignettes/antareslogo.png b/vignettes/antareslogo.png new file mode 100644 index 0000000..c434774 Binary files /dev/null and b/vignettes/antareslogo.png differ diff --git a/vignettes/data_for_antaresViz_vignette_extralight.Rdata b/vignettes/data_for_antaresViz_vignette_extralight.Rdata new file mode 100644 index 0000000..1030ef1 Binary files /dev/null and b/vignettes/data_for_antaresViz_vignette_extralight.Rdata differ diff --git a/vignettes/maplyout_resized.gif b/vignettes/maplyout_resized.gif new file mode 100644 index 0000000..5fe4738 Binary files /dev/null and b/vignettes/maplyout_resized.gif differ diff --git a/vignettes/plot_resized.gif b/vignettes/plot_resized.gif new file mode 100644 index 0000000..3f84eb4 Binary files /dev/null and b/vignettes/plot_resized.gif differ