#' ui function of modelResults3D module
#'
#' @param id namespace
#' @param title title in tab
#'
#' @export
modelResults3DUI <- function(id, title = ""){
ns <- NS(id)
tabPanel(
title,
id = id,
value = id,
fluidRow(
class = "modeling-content",
# left sidebar ----
sidebarPanel(
width = 2,
style = "position:fixed; width:14%; max-width:220px; overflow-y:auto; height:88%",
importDataUI(ns("modelUpload"), label = "Import Model"),
downloadDSSMModelUI(ns = ns),
selectInput(ns("dataSource"),
"Data source",
choices = c("Database" = "db",
"Upload file" = "file",
"Saved map" = "model"),
selected = "db"),
conditionalPanel(
condition = "input.dataSource == 'file'",
importDataUI(ns("importData"), "Import Data"),
tags$br(),
tags$br(),
radioButtons(
inputId = ns("CoordType"),
label = "Coordinate format",
choiceNames = c("decimal degrees \n (e.g. \"40.446\" or \"79.982\")",
"degrees decimal minutes \n (e.g. \"40\u00B0 26.767\u2032 N\" or \"79\u00B0 58.933 W\")",
"degrees minutes seconds \n (e.g. \"40\u00B0 26\u2032 46\u2033 N\" or \"79\u00B0 58\u2032 56\u2033 W\")"),
choiceValues = c("decimal degrees", "degrees decimal minutes", "degrees minutes seconds")),
tags$hr(),
ns = ns
),
conditionalPanel(
condition = "input.dataSource == 'model'",
ns = ns,
selectInput(
ns("savedModel"),
"Saved Map",
choices = NULL,
selected = NULL
)
),
conditionalPanel(
condition = "input.dataSource != 'model'",
ns = ns,
selectInput(inputId = ns("IndependentX"),
label = "Dependent variable:",
choices = c("d15N", "d13C")),
radioButtons(inputId = ns("IndependentType"),
label = "Dependent variable type:",
choices = c("numeric", "categorical")),
selectInput(inputId = ns("IndependentUnc"),
label = "Uncertainty(optional) of dep. var.:",
choices = c("")),
selectInput(inputId = ns("DateType"),
label = "Date type:",
choices = c("Interval", "Mean + 1 SD uncertainty",
"Single point"), selected = "Interval"),
selectInput(inputId = ns("DateOne"),
label = "Mean or lower time point:",
choices = c("")),
conditionalPanel(
condition = "input.DateType == 'Interval' || input.DateType == 'Mean + 1 SD uncertainty'",
selectInput(inputId = ns("DateTwo"),
label = "Standard deviation or upper time point:",
choices = c("")),
ns = ns),
selectInput(inputId = ns("Longitude"),
label = "Longitude variable:",
choices = c("Longitude")),
selectInput(inputId = ns("Latitude"),
label = "Latitude variable:",
choices = c("Latitude")),
selectInput(inputId = ns("Site"),
label = "Site/ID (optional):",
choices = c("")),
radioButtons(inputId = ns("SplineType"),
label = "Smooth type",
choices = c("planar" = "1", "spherical" = "2"),
selected = "1"),
dataCenterUI(ns),
conditionalPanel(
condition = "input.SplineType == 2",
sliderInput(inputId = ns("Smoothing"),
label = "Number of spatial basis functions",
min = 10, max = 250, value = 30, step = 5),
sliderInput(inputId = ns("SmoothingT"),
label = "Number of time basis functions",
min = 4, max = 50, value = 12, step = 1),
ns = ns
),
conditionalPanel(
condition = "input.SplineType == 1",
sliderInput(inputId = ns("SmoothingClassic"),
label = "Number of spatial basis functions",
min = 10, max = 1000, value = 150, step = 5),
ns = ns
),
radioButtons(inputId = ns("Penalty"),
label = "Extrapolation behaviour",
choices = c("constant" = "1", "linear" = "2"),
selected = "2"),
checkboxInput(inputId = ns("Outlier"),
label = "Remove model outliers",
value = FALSE, width = "100%"),
conditionalPanel(
condition = "input.Outlier == true",
sliderInput(inputId = ns("OutlierValue"),
label = "Model outlier threshold in standard deviations",
min = 2, max = 8, value = 4, step = 0.1),
ns = ns
),
checkboxInput(inputId = ns("OutlierD"),
label = "Remove data outliers",
value = FALSE, width = "100%"),
conditionalPanel(
condition = "input.OutlierD == true",
sliderInput(inputId = ns("OutlierValueD"),
label = "Data outlier threshold in standard deviations",
min = 2, max = 8, value = 4, step = 0.1),
ns = ns
),
checkboxInput(inputId = ns("modelArea"),
label = "Restrict model area",
value = FALSE, width = "100%"),
conditionalPanel(
condition = "input.modelArea == true",
tags$strong("Latitude restriction:"),
numericInput(inputId = ns("mALat1"),
label = "Lower",
min = -90, max = 90, value = c(-90), width = "80%"),
numericInput(inputId = ns("mALat2"),
label = "Upper",
min = -90, max = 90, value = c(90), width = "80%"),
tags$strong("Longitude restriction:"),
numericInput(inputId = ns("mALong1"),
label = "Lower",
min = -180, max = 180, value = c(-180), width = "80%"),
numericInput(inputId = ns("mALong2"),
label = "Upper",
min = -180, max = 180, value = c(180), width = "80%"),
ns = ns
),
checkboxInput(inputId = ns("Bayes"),
label = "Bayesian model",
value = FALSE, width = "100%"),
conditionalPanel(
checkboxInput(inputId = ns("sdVar"),
label = "Varying standard error",
value = FALSE, width = "100%"),
condition = "input.Bayes == true",
conditionalPanel(
condition = "input.DateType == 'Interval' || input.DateType == 'Mean + 1 SD uncertainty'",
radioButtons(inputId = ns("dateUnc"),
label = "Distribution of date uncertainty",
choices = c("normal (sd = 1/4 width)" = "normal",
"normal (sd = 1/2 width)" = "normal2",
"uniform (full width)" = "uniform",
"mid point" = "point")),
ns = ns),
sliderInput(inputId = ns("Iter"),
label = "Number of MCMC iterations",
min = 100, max = 100000, value = 3000, step = 100),
sliderInput(inputId = ns("burnin"), label = "Number of burnin iterations",
value = 1000, min = 100, max = 10000, step = 100),
sliderInput(inputId = ns("nChains"), label = "Number of MCMC chains",
value = 1, min = 1, max = 16, step = 1),
sliderInput(inputId = ns("thinning"), label = "MCMC thinning (keep every x-th sample)",
value = 10, min = 1, max = 20, step = 1),
sliderInput(inputId = ns("smoothConst"),
label = "Amount of smoothing",
min = 0.2, max = 5, value = 1, step = 0.1),
ns = ns)
),
actionButton( ns("start"), "Start"),
conditionalPanel(
condition = conditionPlot(ns("DistMap")),
checkboxInput(inputId = ns("fixCol"),
label = "Fix colours and ranges ",
value = FALSE, width = "100%")
),
conditionalPanel(
ns = ns,
condition = "input.dataSource != 'model'",
tags$hr(),
tags$h4("Batch Modeling"),
batchModelingUI(ns("batchModeling"))
)
),
# main panel ----
mainPanel(
width = 8,
previewDataUI(id = ns("preview"), title = sprintf("%s Input Data", title)),
tags$hr(),
tags$h4("Map"),
div(class = "aspect-16-9", div(
plotOutput(outputId = ns("DistMap"), width = "100%", height = "100%")
)),
conditionalPanel(
condition = conditionPlot(ns("DistMap")),
htmlOutput(ns("centerEstimate"), container = function(...) div(..., style = "text-align:center;")),
selectInput(ns("IndSelect"), label = "Independent category", choices = NULL),
tags$br(),
tags$br(),
fluidRow(column(width = 3,
conditionalPanel(
condition = "input.mapType == 'Map'",
ns = ns,
div(
class = "move-map",
uiOutput(ns("move"))
))
),
column(width = 3,
offset = 6,
align = "right",
plotExportButton(ns("export"))
)),
conditionalPanel(
condition = "input.mapType == 'Map'",
ns = ns,
timeAndMapSectionUI(ns("sectionOfMap"), label = "Time and Map Section"),
div(div(
style = 'display:inline-block',
class = "save-plot-container",
textInput(ns("saveMapName"), NULL, placeholder = "Name for Map"),
actionButton(ns("saveMap"), "Save map"),
dataExportButton(ns("exportData")),
conditionalPanel(
condition = "input.Bayes == true",
modelDiagButton(ns("modelDiag")),
ns = ns)
)),
actionButton(ns("add_btn2D"), "Add data point"),
actionButton(ns("rm_btn2D"), "Remove data point"),
actionButton(ns("ok"), "Ok"),
uiOutput(ns("pointInput2D"))
)
),
# possibly add input for timerange also later ----
conditionalPanel(
condition = "input.mapType == 'Time course'",
ns = ns,
sliderInput(inputId = ns("trange"),
label = "Time range",
min = 0, max = 15000, value = c(0, 15000), width = "100%"),
actionButton(ns("add_btn"), "Add data point"),
actionButton(ns("rm_btn"), "Remove data point"),
# colourInput(ns("col_btn"), "Select colour of data point"),
# sliderInput(ns("size_btn"), "Size data point", min = 0.1, max = 10, value = 1),
uiOutput(ns("pointInput")),
conditionalPanel(
condition = "input.pointsTime == true",
ns = ns,
dataExportButton(ns("exportDataTimeCourse"), title = "Export time course plot data"),
dataExportButton(ns("exportDataTimeCoursePred"), title = "Export time course plot predictions data")
)
)
),
# right sidebar ----
sidebarPanel(
width = 2,
style = "position:fixed; width:14%; max-width:220px; overflow-y:auto; height:88%",
radioButtons(inputId = ns("Centering"),
label = "Map Centering",
choices = c("0th meridian" = "Europe", "160th meridian" = "Pacific")),
helpTextCenteringUI(ns),
zScaleUI(ns("zScale")),
radioButtons(inputId = ns("mapType"), label = "Plot type", inline = TRUE,
choices = c("Map", "Time course"),
selected = "Map"),
conditionalPanel(
condition = "input.mapType == 'Time course'",
ns = ns,
tags$hr(),
selectInput(inputId = ns("intervalType"), label = "Uncertainty Interval Type",
choices = list("none" = "1",
"1 SEM" = "2",
"1 SD" = "5",
"1 Total_Error" = "3",
"1 SEM & Total_Error" = "4",
"2 SEM" = "6",
"2 SD" = "7",
"2 Total_Error" = "8",
"2 SEM & Total_Error" = "9"), selected = "2"),
checkboxInput(inputId = ns("pointsTime"),
label = "Show nearby points",
value = TRUE, width = "100%"),
conditionalPanel(
condition = "input.pointsTime == true",
checkboxInput(inputId = ns("intTime"),
label = "Show nearby points unc. intervals",
value = FALSE, width = "100%"),
sliderInput(inputId = ns("rangePointsTime"),
label = "Show nearby points / intervals range in km",
min = 10, max = 2500, value = 250, step = 10),
ns = ns),
formatTimeCourseUI(ns("timeCourseFormat")),
tags$hr()
),
radioButtons(inputId = ns("terrestrial"), label = "", inline = TRUE,
choices = list("Terrestrial " = 1, "All" = 3, "Aquatic" = -1),
selected = 1),
checkboxInput(inputId = ns("points"),
label = "Show locations on map",
value = TRUE, width = "100%"),
checkboxInput(inputId = ns("grid"),
label = "Show map grid",
value = TRUE, width = "100%"),
checkboxInput(inputId = ns("scale"),
label = "Show map scale",
value = TRUE, width = "100%"),
checkboxInput(inputId = ns("arrow"),
label = "Show north arrow",
value = TRUE, width = "100%"),
checkboxInput(inputId = ns("titleMain"),
label = "Show plot title",
value = TRUE),
checkboxInput(inputId = ns("titleScale"),
label = "Show colour scale title",
value = TRUE),
checkboxInput(inputId = ns("showScale"),
label = "Show colour scale",
value = TRUE),
checkboxInput(inputId = ns("setAxisLabels"),
label = "Set axis labels",
value = FALSE),
conditionalPanel(
condition = "input.setAxisLabels == true",
textInput(ns("mainLabel"), NULL, placeholder = "main title"),
textInput(ns("yLabel"), NULL, placeholder = "y-axis"),
textInput(ns("xLabel"), NULL, placeholder = "x-axis"),
textInput(ns("scLabel"), NULL, placeholder = "colour scale title"), ns = ns
),
checkboxInput(inputId = ns("setNorth"),
label = "Set north arrow and scale size and position",
value = FALSE),
conditionalPanel(
condition = "input.setNorth == true",
sliderInput(ns("northSize"), "Size north arrow", min = 0, max = 1, value = 0.2),
sliderInput(ns("scalSize"), "Size scale", min = 0, max = 1, value = 0.1),
sliderInput(ns("scaleX"), "Scale x orientation", min = 0, max = 1, value = 0),
sliderInput(ns("scaleY"), "Scale y orientation", min = 0, max = 1, value = 0.1),
sliderInput(ns("NorthX"), "North arrow x orientation", min = 0, max = 1, value = 0.025),
sliderInput(ns("NorthY"), "North arrow y orientation", min = 0, max = 1, value = 0.925),
ns = ns
),
conditionalPanel(
condition = "input.points == true",
sliderInput(inputId = ns("pointSize"),
label = "Location mark size",
min = 0.1, max = 2, value = 1, width = "100%",
step = 0.1), ns = ns),
checkboxInput(inputId = ns("colPSettings"),
label = "Set colour and shape of location marks",
value = FALSE, width = "100%"),
conditionalPanel(
condition = "input.colPSettings == true",
radioButtons(inputId = ns("colFix"),
label = "Fixed or variable location mark colour?", choices = c("fixed", "variable")),
conditionalPanel(
condition = "input.colFix == 'fixed'",
colourInput(inputId = ns("pointCol"),
label = "Colour of location marks",
value = "#2C2161"), ns = ns),
conditionalPanel(
condition = "input.colFix == 'variable'",
selectInput(inputId = ns("pointLabelsVarCol"),
label = "Select point color variable",
choices = c("")),
selectInput(inputId = ns("colorsP"), label = "Colour palette for points",
choices = list("Red-Yellow-Green" = "RdYlGn",
"Yellow-Green-Blue" = "YlGnBu",
"Purple-Orange" = "PuOr",
"Pink-Yellow-Green" = "PiYG",
"Red-Yellow-Blue" = "RdYlBu",
"Yellow-Brown" = "YlOrBr",
"Brown-Turquoise" = "BrBG"),
selected = "RdYlGn"),
ns = ns),
selectInput(inputId = ns("pointShape"), label = "Shape of location marks",
choices = pchChoices(), selected = 4),
ns = ns),
sliderInput(inputId = ns("AddU"),
label = "Location marks and convex hull: Add time uncertainty in years",
min = 0, max = 1000, value = 0, step = 10),
sliderInput(inputId = ns("StdErr"),
label = "Display up to max standard error",
min = 0, max = 10000, value = 10000, width = "100%"),
radioButtons(inputId = ns("interior"),
label = "Apply convex hull",
choices = c("none" = "0", "spatio-temporal" = "1", "time-sliced spatial" = "2"),
selected = "2", width = "100%"),
checkboxInput(inputId = ns("mask"),
label = "Mask / Show output within range of points",
value = FALSE, width = "100%"),
conditionalPanel(
condition = "input.mask == true",
sliderInput(inputId = ns("maskRadius"),
label = "Mask radius in km",
min = 10, max = 2500, value = 500, width = "100%",
step = 10), ns = ns),
selectInput(inputId = ns("Colours"), label = "Colour palette",
choices = list("Red-Yellow-Green" = "RdYlGn",
"Yellow-Green-Blue" = "YlGnBu",
"Purple-Orange" = "PuOr",
"Pink-Yellow-Green" = "PiYG",
"Red-Yellow-Blue" = "RdYlBu",
"Yellow-Brown" = "YlOrBr",
"Brown-Turquoise" = "BrBG"),
selected = "RdYlGn"),
checkboxInput(inputId = ns("reverseCols"),
label = "Reverse colors",
value = FALSE, width = "100%"),
sliderInput(inputId = ns("ncol"),
label = "Approximate number of colour levels",
min = 4, max = 50, value = 20, step = 2, width = "100%"),
checkboxInput(inputId = ns("smoothCols"),
label = "Smooth color transition",
value = FALSE, width = "100%"),
sliderInput(inputId = ns("resolution"),
label = "Plot resolution (px)",
min = 20, max = 500, value = 100, width = "100%",
step = 20),
checkboxInput(inputId = ns("pointLabels"),
label = "Scale point size by variable",
value = FALSE, width = "100%"),
conditionalPanel(
condition = "input.pointLabels == true",
selectInput(inputId = ns("pointLabelsVar"),
label = "Select point size variable",
choices = c("")), ns = ns
),
checkboxInput(inputId = ns("textLabels"),
label = "Add location mark text labels",
value = FALSE, width = "100%"),
conditionalPanel(
condition = "input.textLabels == true",
selectInput(inputId = ns("textLabelsVar"),
label = "Select text label variable",
choices = c("")),
sliderInput(inputId = ns("fontSize"),
label = "Font size)",
min = 0.1, max = 3, value = 1, step = 0.1, width = "100%"),
selectInput(inputId = ns("fontType"),
label = "Select font type",
choices = names(pdfFonts())),
colourInput(inputId = ns("fontCol"),
label = "Colour of font",
value = "#2C2161")
, ns = ns),
centerEstimateUI(ns("centerEstimateParams")),
sliderInput(inputId = ns("AxisSize"),
label = "Axis title font size",
min = 0.1, max = 3, value = 1, step = 0.1, width = "100%"),
sliderInput(inputId = ns("AxisLSize"),
label = "Axis label font size",
min = 0.1, max = 3, value = 1, step = 0.1, width = "100%"),
batchPointEstimatesUI(ns("batch"))
)
)
)
}
#' server function of model Results module
#'
#' @param input input
#' @param output output
#' @param session session
#' @param isoData data
#' @param savedMaps saved Maps
#' @param fruitsData data for export to FRUITS
#'
#' @export
modelResults3D <- function(input, output, session, isoData, savedMaps, fruitsData){
observeSavedMaps(input, output, session, savedMaps, type = c("temporalAvg"))
observeEvent(input$saveMap, {
logDebug("modelResults3D: Button 'Save map' clicked")
mapName <- trimws(input$saveMapName)
if (mapName == ""){
alert("Please provide a map name")
return()
}
map <- createSavedMap(
model = Model(),
predictions = values$predictions,
plot = values$plot,
plotFUN = plotFun(),
type = "temporalAvg",
name = mapName
)
maps <- savedMaps()
maps[[length(maps) + 1]] <- map
savedMaps(maps)
alert(paste0("Map '", mapName, "' was saved"))
updateTextInput(session, "saveMapName", value = "")
})
output$centerEstimate <- renderUI({
logDebug("modelResults3D: Render centerEstimate")
centerEstimate$text()
})
data <- reactiveVal()
observe({
activeData <- switch(
input$dataSource,
db = isoData(),
file = fileImport()
)
req(!is.null(activeData), !identical(data(), activeData))
logDebug("modelResults3D: Update data")
# reset model
Model(NULL)
data(activeData)
})
coordType <- reactive({
logDebug("modelResults3D: Update coordType")
# reset model
Model(NULL)
switch(
input$dataSource,
db = "decimal degrees",
file = input$CoordType
)
})
outputHelpTextCentering(input, output, session)
observeEvent(input$Bayes, {
if (input$Bayes) alert(alertBayesMessage()) else NULL
})
Model <- reactiveVal()
# MODEL DOWN- / UPLOAD ----
uploadedNotes <- reactiveVal(NULL)
subFolder <- "TimeR"
downloadDSSMModel(input, output, session,
dat = data,
model = Model(),
#savedMaps = savedMaps(),
subFolder = subFolder,
tabId = "model3D",
uploadedNotes = uploadedNotes)
uploadedValues <- importDataServer("modelUpload",
title = "Import Model",
importType = "model",
ckanFileTypes = config()[["ckanModelTypes"]],
subFolder = subFolder,
ignoreWarnings = TRUE,
defaultSource = config()[["defaultSourceModel"]],
fileExtension = config()[["fileExtension"]],
options = importOptions(rPackageName = config()[["rPackageName"]]))
observe(priority = 100, {
req(length(uploadedValues()) > 0, !is.null(uploadedValues()[[1]][["data"]]))
logDebug("modelResults3D: Update data after model import")
# reset model
Model(NULL)
fileImport(uploadedValues()[[1]][["data"]])
data(uploadedValues()[[1]][["data"]])
# update notes in tab "Estimates" model download ----
uploadedNotes(uploadedValues()[[1]][["notes"]])
}) %>%
bindEvent(uploadedValues())
previewDataServer(id = "preview", dat = data)
observe(priority = 50, {
req(length(uploadedValues()) > 0, !is.null(uploadedValues()[[1]][["inputs"]]))
logDebug("modelResults3D: Update inputs after model import")
uploadedInputs <- uploadedValues()[[1]][["inputs"]]
## update inputs ----
inputIDs <- names(uploadedInputs)
inputIDs <- inputIDs[inputIDs %in% names(input)]
for (i in 1:length(inputIDs)) {
session$sendInputMessage(inputIDs[i], list(value = uploadedInputs[[inputIDs[i]]]) )
}
}) %>%
bindEvent(uploadedValues())
observe(priority = 10, {
req(length(uploadedValues()) > 0, !is.null(uploadedValues()[[1]][["model"]]))
logDebug("modelResults3D: Update model after model import")
## update model ----
Model(unpackModel(uploadedValues()[[1]][["model"]]))
uploadedSavedMaps <- unpackSavedMaps(uploadedValues()[[1]][["model"]], currentSavedMaps = savedMaps())
savedMaps(c(savedMaps(), uploadedSavedMaps))
}) %>%
bindEvent(uploadedValues())
# RUN MODEL ----
observeEvent(input$start, {
logDebug("modelResults3D: Button 'Start' clicked")
if (input$dataSource == "model") {
if (length(savedMaps()) == 0) return(NULL)
Model(savedMaps()[[as.numeric(input$savedModel)]]$model)
return()
}
values$set <- 0
if (input$IndependentX == "" | input$Latitude == "" |
input$Longitude == "" | input$DateOne == "" |
(input$DateTwo == "" & input$DateType != "Single point")) {
Model(NULL)
return()
}
params <- reactiveValuesToList(input)
params$coordType <- coordType()
model <- estimateMap3DWrapper(data(), params) %>%
tryCatchWithWarningsAndErrors()
Model(model)
updateSelectInput(session, "Centering", selected = input$centerOfData)
})
Independent <- reactive({
names(Model()$data)[1]
})
zoomFromModel <- reactiveVal(50)
observe({
validate(validInput(Model()))
if(input$fixCol == FALSE){
logDebug("modelResults3D: If not fixedCol: update zoom and standard error")
if(Model()$IndependentType == "numeric"){
val <- sd(Model()$data[, isolate(Independent())], na.rm = TRUE)
} else {
val <- 0.5
}
updateSliderInput(session, "StdErr", value = signif(5 * val, 2),
min = 0, max = signif(5 * val, 2),
step = signif(roundUpNice(val, nice = c(1,10)) / 1000, 1))
newZoom <- extractZoomFromLongRange(
rangeLongitude = range(Model()$data$Longitude, na.rm = TRUE),
mapCentering = input$Centering
)
isolate({
zoomFromModel(newZoom)
values$zoom <- newZoom
values$up <- 0
values$right <- 0
})
}
})
output$move <- renderUI({
moveButtons(ns = session$ns)
})
estimationTypeChoices <- reactiveVal(c(
"Mean" = "Mean",
"1 SEM" = "1 SE",
"1 Total_Error" = "1 SETOTAL",
"2 SEM" = "2 SE",
"2 Total_Error" = "2 SETOTAL",
"1 SD" = "1 SD Population",
"2 SD" = "2 SD Population",
"Quantile_Mean" = "Quantile",
"Quantile_Total" = "QuantileTOTAL"
))
observeEvent(input$mapType, {
choices <- switch(
input$mapType,
"Map" = c("Mean" = "Mean",
"1 SEM" = "1 SE",
"1 Total_Error" = "1 SETOTAL",
"2 SEM" = "2 SE",
"2 Total_Error" = "2 SETOTAL",
"1 SD" = "1 SD Population",
"2 SD" = "2 SD Population",
"Quantile_Mean" = "Quantile",
"Quantile_Total" = "QuantileTOTAL"),
"Time course" = c("Mean" = "Mean",
"Quantile_Mean" = "Quantile",
"Quantile_Total" = "QuantileTOTAL")
)
estimationTypeChoices(choices)
})
zSettings <- zScaleServer("zScale",
mapType = reactive(input$mapType),
Model = Model,
fixCol = reactive(input$fixCol),
estimationTypeChoices = estimationTypeChoices,
restrictOption = reactive("show"),
zValuesFun = getZvalues,
zValuesFactor = 3,
IndSelect = input$IndSelect
)
observeEvent(input$up, {
values$up <- values$up + values$zoom / 40
})
observeEvent(input$down, {
values$up <- values$up - values$zoom / 40
})
observeEvent(input$left, {
values$right <- values$right - values$zoom / 40
})
observeEvent(input$right, {
values$right <- values$right + values$zoom / 40
})
observeEvent(input$center, {
values$upperLeftLatitude <- NA
values$upperLeftLongitude <- NA
values$up <- 0
values$right <- 0
})
dateExtent <- reactiveValues(
min = 0,
max = 15000,
mean = 5000,
range = c(0, 15000),
step = 100
)
mapSection <- timeAndMapSectionServer("sectionOfMap",
dateMin = reactive(dateExtent$min),
dateMax = reactive(dateExtent$max),
dateValue = reactive(dateExtent$mean),
dateStep = reactive(dateExtent$step),
zoomValue = zoomFromModel)
observeEvent(mapSection$set, {
mapSectionVars <- names(mapSection)
for (i in mapSectionVars[mapSectionVars != "set"]) {
values[[i]] <- mapSection[[i]]
}
values$up <- 0
values$right <- 0
})
observe({
validate(validInput(Model()))
if(input$dataSource != "model"){
try({
if(input$DateType == "Interval"){
d <- c(data()[, isolate(input$DateOne)],
data()[, isolate(input$DateTwo)])
}
if(input$DateType == "Mean + 1 SD uncertainty"){
d <- c(data()[, isolate(input$DateOne)] + 2 *
data()[, isolate(input$DateTwo)],
data()[, isolate(input$DateOne)] - 2 *
data()[, isolate(input$DateTwo)])
}
if(input$DateType == "Single point"){
d <- data()[, isolate(input$DateOne)]
}
}, silent = TRUE)
} else {
try({d <- Model()$data[, "Date"]}, silent = TRUE)
}
if(exists("d")){
d <- na.omit(d)
dateExtent$mean <- signif(mean(d), digits = 1)
dateExtent$range <- signif(range(d), digits = 1)
dateExtent$step <- signif(roundUpNice(diff(range(d)),
nice = c(1,10)) / 10000,
digits = 2)
dateExtent$min <- signif(min(d) - diff(range(d)) * 0.1, digits = 2)
dateExtent$max <- signif(max(d) + diff(range(d)) * 0.1, digits = 2)
# update plot time
values$time <- dateExtent$mean
# time range update ----
updateSliderInput(
session,
"trange",
value = dateExtent$range,
min = dateExtent$min,
max = dateExtent$max,
step = dateExtent$step
)
}
})
### Add Points
pointDat2D <- reactiveVal({
data.frame(
index = numeric(0),
y = numeric(0),
x = numeric(0),
label = character(0),
pointSize = numeric(0),
pointAlpha = numeric(0),
pointColor = character(0)
)
})
observeEvent(Model(), ignoreNULL = FALSE, {
pointDat2D(data.frame(
index = numeric(0),
y = numeric(0),
x = numeric(0),
label = character(0),
pointSize = numeric(0),
pointAlpha = numeric(0),
pointColor = character(0)
))
})
addRow2D <- function(df) {
rbind(df, data.frame(index = nrow(df) + 1, y = NA,
x = NA, label = "",
pointColor = "black", pointSize = 1,
pointAlpha = 0.5, stringsAsFactors = FALSE))
}
rmRow2D <- function(df) {
if (nrow(df) > 0) df[- nrow(df), , drop = FALSE]
else df
}
observeEvent(input$add_btn2D, {
df <- pointDat2D()
indices <- df$index
lapply(indices, function(index) {
yval <- input[[paste("y", index, sep = "_")]]
xval <- input[[paste("x", index, sep = "_")]]
labelVal <- input[[paste("label", index, sep = "_")]]
pointColor <- input[[paste("pointColor", index, sep = "_")]]
pointSize <- input[[paste("pointSize", index, sep = "_")]]
pointAlpha <- input[[paste("pointAlpha", index, sep = "_")]]
df[index, "pointColor"] <<- if (is.null(pointColor)) "#000000" else pointColor
df[index, "pointSize"] <<- if (is.null(pointSize)) 1 else pointSize
df[index, "pointAlpha"] <<- if (is.null(pointAlpha)) 1 else pointAlpha
df[index, "y"] <<- if (is.null(yval)) NA else yval
df[index, "x"] <<- if (is.null(xval)) NA else xval
df[index, "label"] <<- if (is.null(labelVal)) NA else labelVal
})
pointDat2D(df)
pointDat2D(addRow2D(pointDat2D()))
})
observeEvent(input$rm_btn2D, {
pointDat2D(rmRow2D(pointDat2D()))
})
inputGroup2D <- reactive({
createPointInputGroup2D(pointDat2D(), ns = session$ns)
})
pointDatOK <- eventReactive(input$ok, ignoreNULL = FALSE, {
df <- pointDat2D()
indices <- df$index
lapply(indices, function(index) {
yval <- input[[paste("y", index, sep = "_")]]
xval <- input[[paste("x", index, sep = "_")]]
labelVal <- input[[paste("label", index, sep = "_")]]
pointColor <- input[[paste("pointColor", index, sep = "_")]]
pointSize <- input[[paste("pointSize", index, sep = "_")]]
pointAlpha <- input[[paste("pointAlpha", index, sep = "_")]]
df[index, "pointColor"] <<- if (is.null(pointColor)) "#000000" else pointColor
df[index, "pointSize"] <<- if (is.null(pointSize)) 1 else pointSize
df[index, "pointAlpha"] <<- if (is.null(pointAlpha)) 1 else pointAlpha
df[index, "y"] <<- if (is.null(yval)) NA else yval
df[index, "x"] <<- if (is.null(xval)) NA else xval
df[index, "label"] <<- if (is.null(labelVal)) NA else labelVal
})
pointDat2D(df)
return(pointDat2D())
})
centerEstimate <- centerEstimateServer("centerEstimateParams",
predictions = reactive(values$predictions),
mapType = reactive(input$mapType))
formatTimeCourse <- formatTimeCourseServer("timeCourseFormat")
plotFun <- reactive({
function(model, time = values$time, returnPred = FALSE,...){
pointDat = pointDat()
pointDatOK = pointDatOK()
if(input$fixCol == FALSE){
zoom <- values$zoom
rangey <- - diff(range(model$data$Latitude, na.rm = TRUE)) / 2 +
max(model$data$Latitude, na.rm = TRUE) + values$up
if(!is.na(values$upperLeftLatitude)){
rangey <- values$upperLeftLatitude + values$up + c(- zoom / 2 , 0)
} else {
rangey <- rangey + c( - zoom / 4, zoom / 4)
}
if(input$Centering == "Europe"){
rangex <- - diff(range(model$data$Longitude, na.rm = TRUE)) / 2 +
max(model$data$Longitude, na.rm = TRUE) + values$right
if(!is.na(values$upperLeftLongitude)){
rangex <- values$upperLeftLongitude + values$right + c(0, zoom)
} else {
rangex <- rangex + c( - zoom / 2, zoom / 2)
}
} else{
dataPac <- model$data
dataPac$Longitude[model$data$Longitude < -20] <- dataPac$Longitude[model$data$Longitude < -20] + 200
dataPac$Longitude[model$data$Longitude >= -20] <- (- 160 + dataPac$Longitude[model$data$Longitude >= -20])
rangex <- - diff(range(dataPac$Longitude, na.rm = TRUE)) / 2 +
max(dataPac$Longitude, na.rm = TRUE) + values$right
if(!is.na(values$upperLeftLongitude)){
rangex <- values$upperLeftLongitude + values$right
if(rangex < -20) rangex <- rangex + 200
if(rangex >= -20) rangex <- rangex - 160
rangex <- rangex + c(0, zoom)
} else {
rangex <- rangex + c( - zoom / 2, zoom / 2)
}
}
if(rangex[2] > 180){
rangex <- c(180 - zoom, 180)
}
if(rangex[1] < -180){
rangex <- c(-180, -180 + zoom)
}
if(rangey[2] > 90){
coordDiff <- rangey[2] - 90
rangey <- pmin(90, pmax(-90, rangey - coordDiff))
}
if(rangey[1] < -90){
coordDiff <- rangey[1] + 90
rangey <- pmin(90, pmax(-90, rangey - coordDiff))
}
values$rangex <- rangex
values$rangey <- rangey
}
if(input$smoothCols){
values$ncol <- 200
} else {
if(input$fixCol == FALSE){
values$ncol <- input$ncol
}
}
textLabels <- NULL
if(input$textLabels & !is.null(input$textLabelsVar) & input$textLabelsVar != ""){
textLabels <- (data())[, input$textLabelsVar, drop = FALSE]
if(nrow(textLabels) == 0){
textLabels = NULL
}
}
pointLabels <- NULL
if(input$pointLabels & !is.null(input$pointLabelsVar) & input$pointLabelsVar != ""){
pointLabels <- (data())[, input$pointLabelsVar, drop = FALSE]
if(nrow(pointLabels) == 0){
pointLabels = NULL
}
}
pointColLabels <- NULL
if(input$colFix == "variable" & !is.null(input$pointLabelsVarCol) & input$pointLabelsVarCol != ""){
pointColLabels <- (data())[, input$pointLabelsVarCol, drop = FALSE]
if(nrow(pointColLabels) == 0){
pointColLabels = NULL
}
}
# PLOT MAP ----
if(input$mapType == "Time course"){
plotTimeCourse(model,
IndSelect = input$IndSelect,
trange = input$trange,
independent = isolate(Independent()),
resolution = input$resolution,
centerX = centerEstimate$centerX(),
centerY = centerEstimate$centerY(),
rangey = zSettings$range,
limitz = zSettings$limit,
seType = input$intervalType,
pointDat = pointDat,
pointsTime = input$pointsTime,
returnPred = returnPred,
rangePointsTime = input$rangePointsTime,
intTime = input$intTime,
formatTimeCourse = formatTimeCourse(),
...) %>%
tryCatchWithWarningsAndErrors(errorTitle = "Plotting failed")
} else {
req(zSettings$estType)
plotMap3D(
model,
IndSelect = input$IndSelect,
time = time,
estType = zSettings$estType,
estQuantile = zSettings$Quantile,
rangez = zSettings$range,
limitz = zSettings$limit,
showModel = zSettings$showModel,
points = input$points,
pointSize = input$pointSize,
StdErr = input$StdErr,
rangex = values$rangex,
rangey = values$rangey,
mask = input$mask,
maskRadius = input$maskRadius,
addU = input$AddU,
pColor = input$pointCol,
pointShape = as.numeric(input$pointShape),
textLabels = textLabels,
pointLabels = pointLabels,
pointColLabels = pointColLabels,
colorsP = input$colorsP,
fontSize = input$fontSize,
fontType = input$fontType,
fontCol = input$fontCol,
centerMap = input$Centering,
resolution = input$resolution,
interior = as.numeric(input$interior),
ncol = values$ncol,
terrestrial = input$terrestrial,
colors = input$Colours,
reverseColors = input$reverseCols,
arrow = input$arrow,
grid = input$grid,
scale = input$scale,
titleMain = !input$titleMain,
titleScale = !input$titleScale,
showScale = input$showScale,
setAxisLabels = input$setAxisLabels,
mainLabel = input$mainLabel,
yLabel = input$yLabel,
xLabel = input$xLabel,
scLabel = input$scLabel,
northSize = input$northSize,
scalSize = input$scalSize,
scaleX = input$scaleX,
scaleY = input$scaleY,
NorthX = input$NorthX,
NorthY = input$NorthY,
AxisSize = input$AxisSize,
AxisLSize = input$AxisLSize,
pointDat = pointDatOK,
...
) %>%
tryCatchWithWarningsAndErrors(errorTitle = "Plotting failed")
}
}
})
output$DistMap <- renderPlot({
validate(validInput(Model()))
withProgress({
res <- plotFun()(Model())
}, min = 0, max = 1, value = 0.8, message = "Plotting map ...")
values$predictions <- res$XPred
values$plot <- recordPlot()
})
values <- reactiveValues(plot = NULL, predictions = NULL,
set = 0,
upperLeftLongitude = NA,
upperLeftLatitude = NA,
zoom = 50)
observe(priority = 75, {
numVars <- unlist(lapply(names(data()), function(x){
if (
(is.integer(data()[[x]]) | is.numeric(data()[[x]]) | sum(!is.na(as.numeric((data()[[x]])))) > 2) #&
#!(x %in% c("Latitude", "Longitude"))
)
x
else
NULL
}))
timeVars <- unlist(lapply(names(data()), function(x){
if (grepl("date", x, ignore.case = TRUE)
)
x
else
NULL
}))
selectedTextLabel <- NULL
selectedLongitude <- NULL
if (input$dataSource == "db" & ("longitude" %in% names(data()))){
selectedLongitude <- "longitude"
}
selectedLatitude <- NULL
if (input$dataSource == "db" & ("latitude" %in% names(data()))){
selectedLatitude <- "latitude"
}
selectedSite <- NULL
if (input$dataSource == "db" & ("site" %in% names(data()))){
selectedSite <- "site"
}
updateSelectInput(session, "IndependentX", choices = c("", setdiff(numVars, timeVars)))
updateSelectInput(session, "IndependentUnc", choices = c("", setdiff(numVars, timeVars)))
updateSelectInput(session, "Longitude", choices = c("", names(data())),
selected = selectedLongitude)
updateSelectInput(session, "Latitude", choices = c("", names(data())),
selected = selectedLatitude)
updateSelectInput(session, "Site", choices = c("", names(data())),
selected = selectedSite)
updateSelectInput(session, "textLabelsVar", choices = c("", names(data())),
selected = selectedTextLabel)
updateSelectInput(session, "pointLabelsVar", choices = c("", names(data())),
selected = selectedTextLabel)
updateSelectInput(session, "pointLabelsVarCol", choices = c("", names(data())),
selected = selectedTextLabel)
# if (input$dataSource == "db"){
# updateSelectInput(session, "DateOne", choices = c("", timeVars))
# updateSelectInput(session, "DateTwo", choices = c("", timeVars))
# } else {
updateSelectInput(session, "DateOne", choices = c("", numVars))
updateSelectInput(session, "DateTwo", choices = c("", numVars))
#}
}) %>%
bindEvent(data())
observe({
if(input$DateType == "Interval"){
updateRadioButtons(session, "dateUnc", choices = c("normal (sd = 1/4 width)" = "normal",
"normal (sd = 1/2 width)" = "normal2",
"uniform (full width)" = "uniform",
"mid point" = "point"))
}
if(input$DateType == "Mean + 1 SD uncertainty"){
updateRadioButtons(session, "dateUnc", choices = c("uniform (2xSD input)" = "uniform",
"uniform (1xSD input)" = "uniform2",
"mean point" = "point",
"normal (sd = 1/4 width)" = "normal"))
}
})
observe({
req(Model())
if(class(Model()) != "character" && Model()$IndependentType != "numeric"){
shinyjs::show(id = "IndSelect")
shinyjs::hide(id = "sdVar")
updateSelectInput(session, "IndSelect", choices = names(Model()$model))
} else {
shinyjs::hide(id = "IndSelect")
shinyjs::show(id = "sdVar")
}
})
## Import Data ----
importedDat <- importDataServer("importData")
fileImport <- reactiveVal(NULL)
observe({
logDebug("modelResults3D: Update fileImport")
# reset model
Model(NULL)
if (length(importedDat()) == 0 || is.null(importedDat()[[1]])) fileImport(NULL)
req(length(importedDat()) > 0, !is.null(importedDat()[[1]]))
data <- importedDat()[[1]]
valid <- validateImport(data, showModal = TRUE)
if (!valid){
showNotification("Import is not valid.")
fileImport(NULL)
} else {
fileImport(data)
}
}) %>% bindEvent(importedDat())
dataFun <- reactive({
req(Model())
function() {
outlier <- Model()$outlier
outlierDR <- Model()$outlierDR
allData <- data()
modelData <- Model()$data
filtered <- which(rownames(allData) %in% rownames(modelData))
allData <- allData[which(rownames(allData) %in% unique(c(filtered, outlier))), ]
allData$Outlier <- "non-outlier"
allData$Outlier[which(rownames(allData) %in% outlier)] <- "model outlier"
allData$Outlier[which(rownames(allData) %in% outlierDR)] <- "data outlier"
return(allData)
}
})
dataTimeCourse <- reactive({
req(Model())
function(){
tData <- plotFun()(Model())
if(!is.null(tData)){
allData <- data()
tData <- allData[which(rownames(allData) %in% rownames(tData)), ]
return(tData)
} else {
return(data.frame())
}
}
})
dataTimeCoursePred <- reactive({
req(Model())
function(){
tData <- plotFun()(Model(), returnPred = TRUE)
if(!is.null(tData)){
return(tData)
} else {
return(data.frame())
}
}
})
### Add Points
pointDat <- reactiveVal({
data.frame(
index = numeric(0),
y = numeric(0),
ymin = numeric(0),
ymax = numeric(0),
x = numeric(0),
xmin = numeric(0),
xmax = numeric(0),
group = character(0),
pointSize = numeric(0),
pointAlpha = numeric(0),
pointColor = character(0)
)
})
observeEvent(Model(), ignoreNULL = FALSE, {
pointDat(data.frame(
index = numeric(0),
y = numeric(0),
ymin = numeric(0),
ymax = numeric(0),
x = numeric(0),
xmin = numeric(0),
xmax = numeric(0),
pointSize = numeric(0),
pointAlpha = numeric(0),
pointColor = character(0)
))
})
addRow <- function(df) {
rbind(df, data.frame(index = nrow(df) + 1, y = NA,
ymin = NA, ymax = NA, x = NA,
xmin = NA, xmax = NA,
pointColor = "black", pointSize = 1,
pointAlpha = 0.5, stringsAsFactors = FALSE))
}
rmRow <- function(df) {
if (nrow(df) > 0) df[- nrow(df), , drop = FALSE]
else df
}
observeEvent(input$add_btn, {
df <- pointDat()
indices <- df$index
lapply(indices, function(index) {
yval <- input[[paste("yT", index, sep = "_")]]
yminval <- input[[paste("yminT", index, sep = "_")]]
ymaxval <- input[[paste("ymaxT", index, sep = "_")]]
xminval <- input[[paste("xminT", index, sep = "_")]]
xmaxval <- input[[paste("xmaxT", index, sep = "_")]]
xval <- input[[paste("xT", index, sep = "_")]]
pointColor <- input[[paste("pointColorT", index, sep = "_")]]
pointSize <- input[[paste("pointSizeT", index, sep = "_")]]
pointAlpha <- input[[paste("pointAlphaT", index, sep = "_")]]
df[index, "pointColor"] <<- if (is.null(pointColor)) "#000000" else pointColor
df[index, "pointSize"] <<- if (is.null(pointSize)) 1 else pointSize
df[index, "pointAlpha"] <<- if (is.null(pointAlpha)) 1 else pointAlpha
df[index, "y"] <<- if (is.null(yval)) NA else yval
df[index, "ymin"] <<- if (is.null(yminval)) NA else yminval
df[index, "ymax"] <<- if (is.null(ymaxval)) NA else ymaxval
df[index, "x"] <<- if (is.null(xval)) NA else xval
df[index, "xmin"] <<- if (is.null(xminval)) NA else xminval
df[index, "xmax"] <<- if (is.null(xmaxval)) NA else xmaxval
})
pointDat(df)
pointDat(addRow(pointDat()))
})
observeEvent(input$rm_btn, {
pointDat(rmRow(pointDat()))
})
inputGroup <- reactive({
createPointInputGroup(pointDat(), ns = session$ns)
})
output$pointInput2D <- renderUI(inputGroup2D())
output$n2D <- reactive(nrow(pointDat2D()))
outputOptions(output, "n2D", suspendWhenHidden = FALSE)
output$pointInput <- renderUI(inputGroup())
output$n <- reactive(nrow(pointDat()))
outputOptions(output, "n", suspendWhenHidden = FALSE)
###
callModule(modelDiagnostics, "modelDiag", model = Model)
callModule(dataExport, "exportData", data = dataFun, filename = "modelData")
callModule(dataExport, "exportDataTimeCourse", data = dataTimeCourse, filename = "timeCourseData")
callModule(dataExport, "exportDataTimeCoursePred", data = dataTimeCoursePred, filename = "timeCourseDataPred")
callModule(plotExport, "export", reactive(values$plot), "spatio-temporal-average",
predictions = reactive(values$predictions),
plotFun = plotFun,
Model = Model,
mapType = reactive(input$mapType)
)
callModule(batchPointEstimates, "batch", plotFun, time = TRUE, fruitsData = fruitsData, Model = Model)
modelParams <- reactive({
params <- reactiveValuesToList(input)
params$coordType <- coordType()
params
})
batchModel <- callModule(batchModeling, "batchModeling", data = data, plotFun = plotFun,
modelParams = modelParams, type = "temporalAvg",
savedMaps = savedMaps, estimateWrapper = estimateMap3DWrapper)
observeEvent(batchModel(), {
Model(batchModel())
})
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.