library(shiny)
library(shinythemes)
library(shinyWidgets)
library(shinyjs)
##
## Attaching package: 'shinyjs'
## The following object is masked from 'package:shinyWidgets':
##
## alert
## The following object is masked from 'package:shiny':
##
## runExample
## The following objects are masked from 'package:methods':
##
## removeClass, show
# Interfaz de usuario
ui <- fluidPage(
useShinyjs(), # Para funcionalidades JavaScript
theme = shinytheme("yeti"), # Base theme
tags$head(
tags$style(HTML("
body {
background-color: #f5faf5;
font-family: Arial, sans-serif;
}
.well {
background-color: white;
border-color: #81c784;
}
.btn-success {
background-color: #4caf50;
border-color: #388e3c;
}
.btn-success:hover {
background-color: #388e3c;
}
h2 {
color: #2e7d32;
border-bottom: 2px solid #81c784;
padding-bottom: 10px;
}
#resultado {
background-color: #e8f5e9;
border-left: 5px solid #2e7d32;
padding: 15px;
margin-top: 20px;
border-radius: 5px;
}
.title-panel {
text-align: center;
color: #2e7d32;
}
.recomendaciones {
background-color: #ffffff;
border: 1px solid #81c784;
border-radius: 5px;
padding: 15px;
margin-top: 15px;
}
.color-scale {
display: flex;
margin: 10px 0;
}
.color-box {
width: 50px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
}
.progress-bar {
height: 20px;
background-color: #e0e0e0;
border-radius: 10px;
margin: 10px 0;
}
.progress {
height: 100%;
border-radius: 10px;
background-color: #4caf50;
text-align: center;
color: white;
font-weight: bold;
line-height: 20px;
}
"))
),
div(class = "title-panel",
h1("Producción de Tomate UNAL"),
h4("Estimación de cosecha del # racimo")
),
sidebarLayout(
sidebarPanel(
width = 4,
numericInput("area", "Área de cultivo (m²):", value = 1000, min = 1),
numericInput("densidad", "Densidad de siembra (Plantas/m²):",
value = 2.5, min = 0.1, step = 0.1),
numericInput("flores", "Número de flores por racimo:",
value = 12, min = 1),
numericInput("Racimos", "Número de racimos por planta:",
value = 12, min = 1),
numericInput("frutos", "Número de frutos por racimo:",
value = 8, min = 1),
numericInput("peso", "Peso promedio de un tomate del racimo (Gramos):",
value = 80, min = 1),
selectInput("variedad", "Variedad de tomate:",
choices = c("TRONUS", "Cherry", "Otro"),
selected = "TRONUS"),
actionButton("calcular", "Calcular Producción",
class = "btn-success btn-block")
),
mainPanel(
width = 8,
uiOutput("resultado"),
conditionalPanel(
condition = "input.calcular > 0",
div(class = "recomendaciones",
h3("Recomendaciones de Cosecha y Poscosecha"),
actionButton("mostrar_recomendaciones", "Ver Recomendaciones",
class = "btn-info btn-block"),
hidden(
div(id = "panel_recomendaciones",
h4("Escala de Color para Cosecha:"),
div(class = "color-scale",
div(class = "color-box", style = "background-color: #4caf50;", "Verde"),
div(class = "color-box", style = "background-color: #ff9800;", "Pintón"),
div(class = "color-box", style = "background-color: #f44336;", "Maduro")
),
h4("Herramientas de Recolección:"),
tags$ul(
tags$li("Tijeras de podar limpias y desinfectadas"),
tags$li("Canastillas plásticas limpias"),
tags$li("Guantes de cosecha"),
tags$li("Carretillas o mesas de cosecha")
),
h4("Recomendaciones de Cosecha:"),
tags$ul(
tags$li("Cosechar en horas frescas del día (mañana temprano)"),
tags$li("No cosechar después de riegos"),
tags$li("Dejar 1 cm de pedúnculo"),
tags$li("Separar los frutos dañados o enfermos")
),
h4("Recomendaciones de Poscosecha:"),
tags$ul(
tags$li("Enfriamiento rápido a 12-15°C para TRONUS, 18-20°C para Cherry"),
tags$li("Humedad relativa del 90-95%"),
tags$li("Evitar almacenamiento con otros productos que produzcan etileno"),
tags$li("Clasificar por tamaño y grado de madurez")
)
)
)
)
)
)
)
)
# Lógica del servidor corregida
server <- function(input, output) {
observeEvent(input$calcular, {
# Validar entradas
req(input$area, input$densidad, input$flores,
input$frutos, input$peso, input$variedad)
# Calcular porcentaje de cuajamiento
porcentaje_cuajamiento <- (input$frutos/input$flores) * 100
# Calcular producción del primer racimo
plantas_totales <- input$area * input$densidad
tomates_primer_racimo <- plantas_totales * input$frutos
peso_total_gramos <- tomates_primer_racimo * input$peso
peso_total_ton <- round(peso_total_gramos / 1000000, 2)
# Crear resultado
output$resultado <- renderUI({
tagList(
h2("Resultados de Producción - Cosecha de 1 Racimo"),
p(strong("Variedad:"), input$variedad),
hr(),
p(strong("Producción estimada del 1 racimo:"), peso_total_ton, "Toneladas (ton)"),
p(strong("Número total de flores:"), round(plantas_totales * input$flores, 0)),
p(strong("Número total de frutos:"), round(tomates_primer_racimo, 0)),
hr(),
div(style = "display: flex; align-items: center; gap: 10px; margin: 15px 0;",
h4("Porcentaje de cuajamiento:", style = "margin: 0; white-space: nowrap;"),
div(style = "flex-grow: 1.5;",
div(class = "progress-bar", style = "height: 30px; background-color: #f0f0f0; border-radius: 5px;",
div(class = "progress",
style = paste0("width:", porcentaje_cuajamiento, "%; height: 100%; background-color: #81c784; color: white;",
"display: flex; align-items: center; justify-content: center; font-size: 14px;",
"border-radius: 5px ", ifelse(porcentaje_cuajamiento == 100, "5px", "0 5px 5px 0"), ";"),
paste0(round(porcentaje_cuajamiento, 1), "%")
)
)
),
span(style = "color: #555; font-size: 0.9em; white-space: nowrap; min-width: 80px;",
em("(Frutos/Flores)"))
),
hr(style = "margin: 15px 0; border-top: 2px solid #81c784;"),
h4("Detalles del cálculo:"),
p("- Área cultivada:", input$area, "m²"),
p("- Densidad de siembra:", input$densidad, "plantas/m²"),
p("- Plantas totales:", round(plantas_totales, 0)),
p("- Flores por racimo:", input$flores),
p("- Frutos por racimo:", input$frutos),
p("- Peso promedio por tomate:", input$peso, "gramos")
)
})
})
# Mostrar/ocultar recomendaciones
observeEvent(input$mostrar_recomendaciones, {
toggle("panel_recomendaciones")
if (input$mostrar_recomendaciones %% 2 == 1) {
updateActionButton(inputId = "mostrar_recomendaciones", label = "Ocultar Recomendaciones")
} else {
updateActionButton(inputId = "mostrar_recomendaciones", label = "Ver Recomendaciones")
}
})
}
# Ejecutar la aplicación
shinyApp(ui = ui, server = server)
Shiny applications not supported in static R Markdown documents