UD03T03_DashboardIoT

Site: Aula Virtual
Course: Desenvolvemento de interfaces - 2DAM - 2526
Book: UD03T03_DashboardIoT
Printed by: Guest user
Date: Saturday, 2 May 2026, 6:30 AM

01_Enunciado_Principal

Β 

πŸ“Š ENUNCIADO GUIADO: DASHBOARD IoT - MONITOR DE SENSORES EN TIEMPO REAL

1. INTRODUCCIΓ“N Y CONTEXTO

πŸ“– DescripciΓ³n del Proyecto

DesarrollarΓ‘s unΒ Dashboard IoT (Internet of Things)Β completo utilizandoΒ JavaFXΒ que simule el monitoreo en tiempo real de un sensor ambiental multiparamΓ©trico. La aplicaciΓ³n mostrarΓ‘ de forma grΓ‘fica y numΓ©rica tres magnitudes fΓ­sicas fundamentales:

  • 🌑️ TemperaturaΒ (Β°C) - Rango: 10-40Β°C, Alerta: >35Β°C
  • πŸ’§Β Humedad relativaΒ (%) - Rango: 20-90%, Alerta: >80%
  • 🌍 PresiΓ³n atmosfΓ©ricaΒ (hPa) - Rango: 980-1040 hPa, Alerta: >1035 hPa

🎯 Funcionalidades Principales

El dashboard implementarΓ‘:

  • βœ…Β ActualizaciΓ³n automΓ‘ticaΒ cada 0.5 segundos mediante Timeline
  • βœ…Β GrΓ‘fico de lΓ­neas interactivoΒ con ventana deslizante temporal (30s)
  • βœ…Β Sistema de alertasΒ por umbrales configurables
  • βœ…Β Filtros dinΓ‘micosΒ para visualizar series especΓ­ficas
  • βœ…Β DiseΓ±o profesionalΒ tipo tarjetas (card-based UI) con CSS moderno
  • βœ…Β GestiΓ³n de memoriaΒ limitando puntos histΓ³ricos (max 200 por serie)


2. DIAGRAMA DE FLUJO GENERAL DEL SISTEMA

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚ initialize() - Controller    β”‚
                    β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
                    β”‚ β”‚1. cargarInformacionSensorβ”‚ β”‚
                    β”‚ β”‚2. configurarEstadoInicialβ”‚ β”‚
                    β”‚ β”‚3. iniciarTimeline()      β”‚ β”‚
                    β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                               β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                              β”‚
                    ↓                             ↓
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚ Timeline activo            β”‚  β”‚ Escuchar eventos   β”‚
         β”‚ cicloPrincipal() cada 0.5s β”‚  β”‚ usuario (UI)       β”‚
         β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                β”‚                                 β”‚
                β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                β”‚  β”‚
                ↓  ↓
    ╔═══════════════════════════════════════════╗
    β•‘      CICLO PRINCIPAL (cada 0.5s)          β•‘
    ╠═══════════════════════════════════════════╣
    β•‘ 1. modelo.generarLectura()                β•‘
    β•‘ 2. actualizarValoresMostrados()           β•‘
    β•‘ 3. modelo.agregarPuntosASeries()          β•‘
    β•‘ 4. actualizarEjeX()                       β•‘
    β•‘ 5. actualizarAvisos()                     β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                β”‚
                ↓
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚ ΒΏUsuario    β”‚  NO
         β”‚ cierra app? β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”
         β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜        β”‚
                β”‚ SÍ            β”‚
                ↓               β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
         β”‚ DiΓ‘logo         β”‚    β”‚
         β”‚ confirmaciΓ³n    β”‚    β”‚
         β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
                β”‚               β”‚
                ↓               β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
         β”‚ timeline.stop() β”‚    β”‚
         β”‚ Platform.exit() β”‚    β”‚
         β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
                β”‚               β”‚
                ↓               β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
         β”‚   FIN APP   β”‚        β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
                                β”‚
                ← ← ← ← ← ← ← β†β”˜
                (Continuar ciclo)

3. ESTRUCTURA DE ARCHIVOS

πŸ“ OrganizaciΓ³n Completa del Proyecto

πŸ“¦ UD03T03_DashboardIoT/
 ┃
 β”—  πŸ“‚ src/
   β”— πŸ“‚ dam/
     ┃
     ┣ πŸ“œ UD03T03_DashboardIoT.java
     ┃   └─ Clase principal (extends Application)
     ┃
     ┣ πŸ“‚ modelo/
     ┃ β”— πŸ“œ IotModel.java
     ┃     └─ LΓ³gica de negocio
     ┃        β€’ GeneraciΓ³n de lecturas simuladas
     ┃        β€’ GestiΓ³n de series XYChart
     ┃        β€’ ValidaciΓ³n de umbrales
     ┃        β€’ CΓ‘lculo de lΓ­mites de ejes
     ┃        β€’ Formateo de datos
     ┃
     ┣ πŸ“‚ controller/
     ┃ β”— πŸ“œ DashboardController.java
     ┃     └─ Controlador MVC
     ┃        β€’ @FXML componentes UI
     ┃        β€’ initialize()
     ┃        β€’ GestiΓ³n de Timeline
     ┃        β€’ Manejadores de eventos
     ┃        β€’ ActualizaciΓ³n de vista
     ┃
     β”— πŸ“‚ vista/
       ┣ πŸ“œ Dashboard.fxml
       ┃   └─ Interfaz grΓ‘fica (XML)
       ┃
       β”— πŸ“œ dashboard.css
           └─ Estilos visuales
 

4.Β πŸ–₯️ ELEMENTOS DEL DASHBOARD (Vista)

La interfaz grΓ‘fica debe mostrarΒ cinco zonas claramente diferenciadas:

  1. Card de informaciΓ³n del sensor

    • Nombre del sensor
    • Modelo
    • UbicaciΓ³n
    • Fecha y hora de la ΓΊltima mediciΓ³n
  2. Card de valores actuales

    • Temperatura actual
    • Humedad actual
    • PresiΓ³n actual
  3. Zona de filtros

    • CheckBox para Temperatura
    • CheckBox para Humedad
    • CheckBox para PresiΓ³n

    El grΓ‘fico mostrarΓ‘ ΓΊnicamente las magnitudes seleccionadas.

  4. GrΓ‘fico

    • Tipo LineChart
    • Eje X: tiempo (simulado)
    • Eje Y: valor medido
  5. Card de avisos

    • Muestra mensajes cuando algΓΊn valor supera un mΓ‘ximo establecido

02_Vista

🎨 DESARROLLO DE LA VISTA (FXML + CSS)

πŸ“‹ PASO 1 VISTA FXML (Dashboard.fxml)

🎯 Propósito

Definir laΒ estructura visualΒ de la interfaz de usuario de forma declarativa usando XML.

1.1. Layout Principal - BorderPane

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   <top>                     β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚
β”‚              β”‚  MenuBar    β”‚                β”‚
β”‚              β”‚  - Archivo  β”‚                β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚               <center>                      β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚   β”‚     HBox principal (horizontal)    β”‚   β”‚
β”‚   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚   β”‚
β”‚   β”‚  β”‚ Columna  β”‚    Columna       β”‚   β”‚   β”‚
β”‚   β”‚  β”‚ Izquierdaβ”‚    Derecha       β”‚   β”‚   β”‚
β”‚   β”‚  β”‚ (360px)  β”‚    (restante)    β”‚   β”‚   β”‚
β”‚   β”‚  β”‚          β”‚                  β”‚   β”‚   β”‚
β”‚   β”‚  β”‚ β€’ Card   β”‚ β€’ Card Filtros   β”‚   β”‚   β”‚
β”‚   β”‚  β”‚  Sensor  β”‚ β€’ Card GrΓ‘fico   β”‚   β”‚   β”‚
β”‚   β”‚  β”‚ β€’ Card   β”‚                  β”‚   β”‚   β”‚
β”‚   β”‚  β”‚  Avisos  β”‚                  β”‚   β”‚   β”‚
β”‚   β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚   β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

ConfiguraciΓ³n del Eje X (Tiempo):

Propiedad Valor Significado
fx:id xAxis Referencia para modificar dinΓ‘micamente
label "Tiempo (s)" Etiqueta del eje
autoRanging false LΓ­mites MANUALES (ventana deslizante)
lowerBound 0 LΓ­mite inferior inicial
upperBound 30 LΓ­mite superior inicial (30s)
tickUnit 5 Marcas cada 5 segundos

ConfiguraciΓ³n del Eje Y (Valor):

Propiedad Valor Significado
fx:id yAxis Referencia (no se modifica en este proyecto)
label "Valor" Etiqueta del eje
autoRanging true Límites AUTOMÁTICOS (se ajustan a datos)

πŸ“‹ PASO 2: ESTILOS CSS (dashboard.css)

2.1. Estilo: Contenedor Principal

CaracterΓ­sticas en EspaΓ±ol:

Selector: .root-pad
β”œβ”€ PROPIEDAD: Color de fondo
β”‚  └─ VALOR: Gris muy claro (#f5f7fb)

Aplicado a:Β HBox principal (contenedor de las dos columnas)


2.2. Estilo: Tarjetas (Cards)

CaracterΓ­sticas:

Selector: .card
β”œβ”€ PROPIEDAD: Color de fondo
β”‚  └─ VALOR: Blanco
β”œβ”€ PROPIEDAD: Color del borde
β”‚  └─ VALOR: Gris muy suave (#e6e9f2)
β”œβ”€ PROPIEDAD: Radio de esquinas del borde
β”‚  └─ VALOR: 12 pΓ­xeles
β”œβ”€ PROPIEDAD: Radio de esquinas del fondo
β”‚  └─ VALOR: 12 pΓ­xeles
β”œβ”€ PROPIEDAD: Relleno interno (padding)
β”‚  └─ VALOR: 14 pΓ­xeles en todos los lados
└─ PROPIEDAD: Efecto visual de sombra (dropshadow)
   β”œβ”€ TIPO: Sombra difuminada gaussiana
   β”œβ”€ COLOR: Negro con 8% de opacidad
   β”œβ”€ RADIO DE DIFUMINADO: 14 pΓ­xeles
   β”œβ”€ FACTOR DE EXTENSIΓ“N: 0.15
   β”œβ”€ DESPLAZAMIENTO HORIZONTAL: 0 pΓ­xeles
   └─ DESPLAZAMIENTO VERTICAL: 3 pΓ­xeles (hacia abajo)

ExplicaciΓ³n de dropshadow:

dropshadow(tipo, color, radio, spread, offsetX, offsetY)
- tipo: gaussian (difuminado suave)
- color: rgba(0,0,0,0.08) (negro 8% opaco)
- radio: 14px (tamaΓ±o del difuminado)
- spread: 0.15 (expansiΓ³n de la sombra)
- offsetX: 0px (sin desplazamiento horizontal)
- offsetY: 3px (desplazada 3px hacia abajo)

2.3. Estilo: TΓ­tulos

Card Title:

Selector: .card-title
β”œβ”€ PROPIEDAD: TamaΓ±o de fuente
β”‚  └─ VALOR: 16 pΓ­xeles
β”œβ”€ PROPIEDAD: Grosor de fuente
β”‚  └─ VALOR: Negrita (bold)
└─ PROPIEDAD: Color del texto
   └─ VALOR: Azul oscuro (#1f2a44)

Section Title:

Selector: .section-title
β”œβ”€ PROPIEDAD: TamaΓ±o de fuente
β”‚  └─ VALOR: 13 pΓ­xeles
β”œβ”€ PROPIEDAD: Grosor de fuente
β”‚  └─ VALOR: Negrita (bold)
└─ PROPIEDAD: Color del texto
   └─ VALOR: Gris azulado oscuro (#2b3553)

2.4. Estilo: Texto Secundario

Selector: .muted
└─ PROPIEDAD: Color del texto
   └─ VALOR: Gris medio (#6b7486)

2.5. Estilo: BotΓ³n con Borde

Selector: .btn-outline
β”œβ”€ PROPIEDAD: Color de fondo
β”‚  └─ VALOR: Transparente
β”œβ”€ PROPIEDAD: Color del borde
β”‚  └─ VALOR: Azul (#2b6cb0)
β”œβ”€ PROPIEDAD: Color del texto
β”‚  └─ VALOR: Azul (#2b6cb0)
β”œβ”€ PROPIEDAD: Radio de esquinas del borde
β”‚  └─ VALOR: 10 pΓ­xeles
β”œβ”€ PROPIEDAD: Radio de esquinas del fondo
β”‚  └─ VALOR: 10 pΓ­xeles
β”œβ”€ PROPIEDAD: Relleno interno (padding)
β”‚  └─ VALORES: vertical=6px, horizontal=14px
└─ PROPIEDAD: Tipo de cursor
   └─ VALOR: Mano (hand) - indica clickeable

Pseudoclase: :hover (cuando el ratΓ³n estΓ‘ encima)
└─ PROPIEDAD: Color de fondo
   └─ VALOR: Azul con 8% de opacidad

2.6. Estilo: Pastillas de Advertencia (alertas)

Selector: .warn-pill
β”œβ”€ PROPIEDAD: Color de fondo
β”‚  └─ VALOR: Rojo con 10% de opacidad
β”œβ”€ PROPIEDAD: Color del texto
β”‚  └─ VALOR: Rojo oscuro (#b91c1c)
β”œβ”€ PROPIEDAD: Relleno interno (padding)
β”‚  └─ VALORES: vertical=8px, horizontal=10px
β”œβ”€ PROPIEDAD: Radio de esquinas del fondo
β”‚  └─ VALOR: 10 pΓ­xeles
β”œβ”€ PROPIEDAD: Radio de esquinas del borde
β”‚  └─ VALOR: 10 pΓ­xeles
└─ PROPIEDAD: Color del borde
   └─ VALOR: Rojo con 25% de opacidad

2.7. Estilo: Pastilla OK (alertas)

Selector: .ok-pill
β”œβ”€ PROPIEDAD: Color de fondo
β”‚  └─ VALOR: Verde con 10% de opacidad
β”œβ”€ PROPIEDAD: Color del texto
β”‚  └─ VALOR: Verde oscuro (#166534)
β”œβ”€ PROPIEDAD: Relleno interno (padding)
β”‚  └─ VALORES: vertical=8px, horizontal=10px
β”œβ”€ PROPIEDAD: Radio de esquinas del fondo
β”‚  └─ VALOR: 10 pΓ­xeles
β”œβ”€ PROPIEDAD: Radio de esquinas del borde
β”‚  └─ VALOR: 10 pΓ­xeles
└─ PROPIEDAD: Color del borde
   └─ VALOR: Verde con 25% de opacidad

2.8. Estilo: GrΓ‘fico

Selector: .chart
└─ PROPIEDAD: Relleno interno (padding)
   └─ VALOR: 6 pΓ­xeles

Selector: .chart-plot-background
└─ PROPIEDAD: Color de fondo del Γ‘rea de trazado
   └─ VALOR: Azul muy claro (#fbfcff)

Selectores: .chart-vertical-grid-lines, .chart-horizontal-grid-lines
└─ PROPIEDAD: Color de trazo de lΓ­neas de cuadrΓ­cula
   └─ VALOR: Negro con 8% de opacidad

🎨 PALETA DE COLORES DEL PROYECTO

Nombre CΓ³digo Uso Principal
Blanco #ffffffΒ /Β white Fondos de cards
Gris muy claro #f5f7fb Fondo general de la app
Gris borde #e6e9f2 Bordes suaves de cards
Gris medio #6b7486 Texto secundario (etiquetas)
Gris azulado #2b3553 SubtΓ­tulos
Azul oscuro #1f2a44 TΓ­tulos principales
Azul #2b6cb0 Botones y acentos
Rojo alerta #dc2626Β /Β #b91c1c Advertencias
Verde OK #16a34aΒ /Β #166534 Estado normal
Azul muy claro #fbfcff Fondo del grΓ‘fico

03_Modelo

πŸ“¦ DESARROLLO DEL MODELO (IotModel.java)

πŸ“‹ PASO 1: MODELO DE DATOS

🎯 Responsabilidad Única del Modelo

  • Almacenar:
    • InformaciΓ³n fija del sensor (nombre, modelo, ubicaciΓ³n).
    • Valores actuales de temperatura, humedad y presiΓ³n.
    • Valores mΓ‘ximos permitidos para cada magnitud.
  • Mantener histΓ³ricos de valores para cada magnitud.
  • Simular nuevas lecturas del sensor:
    • Generar valores aleatorios realistas.
    • Actualizar valores actuales.
    • Guardar el histΓ³rico.
  • Proporcionar los datos necesarios para el grΓ‘fico.
  • Detectar cuΓ‘ndo un valor supera su umbral mΓ‘ximo.

🧱 ESTRUCTURA COMPLETA DE LA CLASE

1.1. Constantes del Sensor

    // =========================
    // CONSTANTES DEL SENSOR
    // =========================
    private final String nombre = "Sonda Ambiental";
    private final String modelo = "DHT-Pro + BMP";
    private final String ubicacion = "Aula 2.1 (ventana)";

PropΓ³sito:Β InformaciΓ³n descriptiva del sensor fΓ­sico simulado.

DiseΓ±o:Β VariablesΒ finalΒ porque son caracterΓ­sticas fijas del dispositivo.


1.2. Umbrales de Alerta

    // =========================
    // UMBRALES (mΓ‘ximos)
    // =========================
    private static final double TEMP_MAX = 35.0;     // Β°C
    private static final double HUM_MAX  = 80.0;     // %
    private static final double PRES_MAX = 1035.0;   // hPa

PropΓ³sito:Β Valores mΓ‘ximos permitidos. Si se superan β†’ generar alerta.

Criterios de diseΓ±o:

  • static final: Constantes compartidas por todas las instancias
  • Valores realistas basados en condiciones ambientales tΓ­picas
  • FΓ‘cilmente modificables para diferentes contextos

1.3. Estado Actual del Sensor

    // =========================
    // VALORES ACTUALES DEL SENSOR
    // =========================
    private double tempActual = 22.0;
    private double humActual  = 45.0;
    private double presActual = 1015.0;

PropΓ³sito:Β Almacenar la ΓΊltima lectura generada.

Valores iniciales:Β Condiciones ambientales normales tΓ­picas de interior:

  • 22Β°C: Temperatura confortable
  • 45%: Humedad moderada
  • 1015 hPa: PresiΓ³n atmosfΓ©rica media a nivel del mar

1.4. Control de Tiempo

Variables explicadas:

Variable Tipo PropΓ³sito
tiempoSimulacion double Tiempo transcurrido desde inicio (eje X grΓ‘fico)
ultimaMedida LocalDateTime Timestamp real de ΓΊltima lectura
formatoFecha DateTimeFormatter Formato "02/02/2026 15:30:45"

1.5. ConfiguraciΓ³n de VisualizaciΓ³n

PropΓ³sito:

Constante Valor FunciΓ³n
MAX_PUNTOS_POR_SERIE 200 Solo se almacenarΓ‘n 200 valores en cada serie
VENTANA_TIEMPO 30.0s Segundos visibles en grΓ‘fico simultΓ‘neamente (eje X)

1.6. Constructor

    /**
     * Constructor: inicializa las series con sus nombres.
     * Los nombres aparecerΓ‘n en la leyenda del grΓ‘fico.
     */

πŸ”§ MΓ‰TODOS PRINCIPALES - DIAGRAMAS DE FLUJO

2.1. MΓ©todo generarLectura()

PropΓ³sito:Β Simular una nueva lectura del sensor con variaciones realistas.

Diagrama de Flujo Detallado:

        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ generarLectura()             β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔══════════════════════════════════════════╗
    β•‘ FASE 1: VARIACIONES NORMALES             β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ tempActual = limitarRango(           β”‚
        β”‚   tempActual + rnd(-0.8, 0.8),       β”‚
        β”‚   10, 40)                             β”‚
        β”‚                                       β”‚
        β”‚ ExplicaciΓ³n:                          β”‚
        β”‚ - Suma variaciΓ³n: -0.8Β°C a +0.8Β°C    β”‚
        β”‚ - Limita resultado entre 10Β°C y 40Β°C β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ humActual = limitarRango(            β”‚
        β”‚   humActual + rnd(-1.6, 1.6),        β”‚
        β”‚   20, 90)                             β”‚
        β”‚                                       β”‚
        β”‚ ExplicaciΓ³n:                          β”‚
        β”‚ - Suma variaciΓ³n: -1.6% a +1.6%      β”‚
        β”‚ - Limita resultado entre 20% y 90%   β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ presActual = limitarRango(           β”‚
        β”‚   presActual + rnd(-1.1, 1.1),       β”‚
        β”‚   980, 1040)                          β”‚
        β”‚                                       β”‚
        β”‚ ExplicaciΓ³n:                          β”‚
        β”‚ - Suma variaciΓ³n: -1.1 a +1.1 hPa    β”‚
        β”‚ - Limita entre 980 y 1040 hPa        β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔══════════════════════════════════════════╗
    β•‘ FASE 2: PICOS ALEATORIOS (eventos)      β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ ΒΏRandom < 0.05? (5% probabilidad)    β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              SÍ ←──      β”‚ NO
              β”‚           ↓
              ↓     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
     β”‚ tempActual +=      β”‚       β”‚
     β”‚ rnd(4, 8)          β”‚       β”‚
     β”‚                    β”‚       β”‚
     β”‚ (Pico: +4Β°C a +8Β°C)β”‚       β”‚
     β”‚ Simula: ventana    β”‚       β”‚
     β”‚ abierta, sol       β”‚       β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
              β”‚                    β”‚
              └────→ β”Œ ← ← ← ← ← β†β”˜
                     β”‚
                     ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ ΒΏRandom < 0.05? (5% prob.)       β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              SÍ ←──      β”‚ NO
              β”‚           ↓
              ↓     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
     β”‚ humActual +=       β”‚       β”‚
     β”‚ rnd(8, 15)         β”‚       β”‚
     β”‚                    β”‚       β”‚
     β”‚ (Pico: +8% a +15%) β”‚       β”‚
     β”‚ Simula: lluvia,    β”‚       β”‚
     β”‚ vapor de agua      β”‚       β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
              β”‚                    β”‚
              └────→ β”Œ ← ← ← ← ← β†β”˜
                     β”‚
                     ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ ΒΏRandom < 0.05? (4% prob. aprox) β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              SÍ ←──      β”‚ NO
              β”‚           ↓
              ↓     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
     β”‚ presActual +=          β”‚   β”‚
     β”‚ rnd(8, 18)             β”‚   β”‚
     β”‚                        β”‚   β”‚
     β”‚ (Pico: +8 a +18 hPa)   β”‚   β”‚
     β”‚ Simula: cambio         β”‚   β”‚
     β”‚ meteorolΓ³gico          β”‚   β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
              β”‚                    β”‚
              └────→ β”Œ ← ← ← ← ← β†β”˜
                     β”‚
                     ↓
    ╔══════════════════════════════════════════╗
    β•‘ FASE 3: ACTUALIZAR TIMESTAMP             β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ ultimaMedida = LocalDateTime.now()   β”‚
        β”‚                                       β”‚
        β”‚ Captura fecha/hora actual del sistemaβ”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
                 (FIN)

CΓ³digo Completo:

    /**
     * Genera una nueva lectura del sensor con variaciones aleatorias.
     * 
     * Algoritmo:
     * 1. Aplica pequeΓ±as variaciones a cada magnitud
     * 2. Limita los valores entre mΓ­nimos y mΓ‘ximos realistas
     * 3. Aleatoriamente genera "picos" para simular eventos
     * 4. Actualiza la marca de tiempo
     */
    public void generarLectura() {
        // FASE 1: Variaciones normales (pequeΓ±os cambios graduales)
        tempActual = limitarRango(tempActual + rnd(-0.8, 0.8), 10, 40);
        humActual  = limitarRango(humActual  + rnd(-1.6, 1.6), 20, 90);
        presActual = limitarRango(presActual + rnd(-1.1, 1.1), 980, 1040);

        // FASE 2: Picos aleatorios (simulan eventos repentinos)
        if (ThreadLocalRandom.current().nextDouble() < 0.05) {
            tempActual += rnd(4, 8);  // Pico de temperatura
        }
        if (ThreadLocalRandom.current().nextDouble() < 0.05) {
            humActual += rnd(8, 15);  // Pico de humedad
        }
        if (ThreadLocalRandom.current().nextDouble() < 0.05) {
            presActual += rnd(8, 18); // Pico de presiΓ³n
        }

        // FASE 3: Actualizar timestamp
        ultimaMedida = LocalDateTime.now();
    }

MΓ©todos Auxiliares:

    /**
     * Genera un nΓΊmero aleatorio en el rango [min, max).
     * Usa ThreadLocalRandom para mejor rendimiento en entornos concurrentes.
     * 
     * @param min Valor mΓ­nimo (inclusivo)
     * @param max Valor mΓ‘ximo (exclusivo)
     * @return NΓΊmero aleatorio en el rango
     */
    private double rnd(double min, double max) {
        return ThreadLocalRandom.current().nextDouble(min, max);
    }

    /**
     * Limita un valor entre un mΓ­nimo y un mΓ‘ximo (clamp).
     * 
     * @param v Valor a limitar
     * @param min LΓ­mite inferior
     * @param max LΓ­mite superior
     * @return Valor limitado
     */
    private double limitarRango(double v, double min, double max) {
        return Math.max(min, Math.min(max, v));
    }

ExplicaciΓ³n del algoritmo clamp:

Si v < min  β†’ retorna min
Si v > max  β†’ retorna max
Si min ≀ v ≀ max β†’ retorna v

2.2. MΓ©todo agregarPuntosASeries()

PropΓ³sito:Β AΓ±adir los valores actuales a las series del grΓ‘fico, si los checkbox de la serie estΓ‘n seleccionados.

Diagrama de Flujo:

        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ agregarPuntosASeries(              β”‚
        β”‚   tempHabilitada,                  β”‚
        β”‚   humHabilitada,                   β”‚
        β”‚   presHabilitada,                  β”‚
        β”‚   incrementoTiempo)                β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ actualizamos el tiempo de la        |
        | simulaciΓ³n con el nuevo incremento  |
        | de timepo                           |
        β”‚ (Avanzar tiempo del eje X)          β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ si el checkbox de la serie          |
        | correspondiente estΓ‘ marcado        β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             SÍ ─        β”‚ NO
                β”‚        |
                ↓        └───────┐
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
    β”‚ AΓ±ade punto a la serie:  β”‚ β”‚
    β”‚ (tiempo, temperatura)    β”‚ β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
               β”‚                 β”‚
               ↓                 β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
    β”‚ Elimina puntos         β”‚   β”‚
    β”‚ antiguos si tamaΓ±o>200 |   β”‚ 
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
               β”‚                 β”‚
               └────→ β”Œ ← ← ← ←  β”˜
                      β”‚
                      ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ repetir para todos lo sensores  β”‚
        β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           SÍ─           β”‚ NO
             β”‚           ↓
      [Mismo proceso]  [Continuar]
             |           β”‚
             β”‚           β”‚
             └────→ β”Œ ← β†β”˜
                    β”‚
                    ↓
                  (FIN)

2.3. MΓ©todo recortarSerie()

PropΓ³sito:Β Evitar crecimiento infinito de memoria eliminando puntos antiguos.

Diagrama de Flujo:

        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ recortarSerie(serie)          β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ tamaΓ±o de serie > MAX_PUNTOS_POR_SERIE |
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              SÍ ←──      β”‚ NO
              β”‚           ↓
              ↓     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚ (FIN)
   β”‚ Si size=250 puntos:        β”‚  β”‚
   β”‚   eliminar = 250 - 200 = 50β”‚  β”‚
   β”‚   Elimina primeros 50    β”‚  β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
            β”‚                      β”‚
            └─────→ β”Œ ← ← ← ← ← ← β”˜
                    β”‚
                    ↓
                  (FIN)

calcularLimiteInferiorX() y calcularLimiteSuperiorX()

PropΓ³sito:Β Crear efecto de "ventana deslizante" en el grΓ‘fico.

Diagrama de Flujo Combinado:

╔══════════════════════════════════════════════════════════╗
β•‘            VENTANA DESLIZANTE - LΓ“GICA                   β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

FASE INICIAL (t ≀ 30s):
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ GrΓ‘fico muestra: [0s ──────── 30s]     β”‚
β”‚ Ventana FIJA al principio              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

TRANSICIΓ“N (t = 35s):
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ calcularLimiteInferiorX()              β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ ΒΏtiempoSimulacion > VENTANA_TIEMPO?β”‚ β”‚
β”‚ β”‚ ΒΏ35 > 30?                          β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚          β”‚ SÍ                          β”‚
β”‚          ↓                             β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ return tiempoSimulacion -          β”‚ β”‚
β”‚ β”‚        VENTANA_TIEMPO              β”‚ β”‚
β”‚ β”‚ return 35 - 30 = 5s                β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

RESULTADO:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ GrΓ‘fico muestra: [5s ──────── 35s]     β”‚
β”‚ Ventana DESLIZANTE (se mueve)          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

FASE AVANZADA (t = 60s):
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ LimiteInferior: 60 - 30 = 30s          β”‚
β”‚ LimiteSuperior: 60s                    β”‚
β”‚ GrΓ‘fico muestra: [30s ─────── 60s]     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2.4. ValidaciΓ³n de Umbrales

MΓ©todos hayAlertaXXX()

PropΓ³sito:Β Detectar si alguna magnitud supera su umbral mΓ‘ximo.

MΓ©todos getMensajeAlertaXXX()

PropΓ³sito:Β Generar mensajes descriptivos para mostrar en la UI con los sigueitne formatos:

  • "Temp = XX.X Β°C (mΓ‘x YY.Y)".
  • "Hum = XX.X % (mΓ‘x YY.Y)"
  • "Pres = XXXX.X hPa (mΓ‘x YYYY.Y)"

Ejemplos de salida:

"Temp = 36.2 Β°C (mΓ‘x 35.0)"
"Hum = 85.7 % (mΓ‘x 80.0)"
"Pres = 1038.4 hPa (mΓ‘x 1035.0)"

2.5. Formateo de Valores

MΓ©todos getXXXFormateada()

PropΓ³sito:Β Convertir valores numΓ©ricos a String con formato especΓ­fico para UI.

  • NΓΊmeros con 1 decimal
  • Fecha "dd/MM/yyyy HH:mm:ss"

2.6. MΓ©todo resetearDatos()

PropΓ³sito:Β Reiniciar toda la simulaciΓ³n a su estado inicial.

Diagrama de Flujo:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ resetearDatos()        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (Eliminar TODOS los puntos   β”‚
β”‚  de la serie temperatura)    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (Eliminar TODOS los puntos   β”‚
β”‚  de la serie humedad)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (Eliminar TODOS los puntos   β”‚
β”‚  de la serie presiΓ³n)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (Resetear contador tiempo)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (Borrar timestamp)           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           ↓
         (FIN)

2.7. Getters BΓ‘sicos

PropΓ³sito: Proporcionar acceso de solo lectura a los atributos privados.

04_Controlador

πŸŽ›οΈ DESARROLLO DEL CONTROLADOR (DashboardController.java)

πŸ“‹ PASO 4: CONTROLADOR MVC


5.1. MΓ©todo initialize() - Ciclo de Vida

Diagrama de Flujo - initialize():


    ╔══════════════════════════════════════╗
    β•‘ PASO 1: cargarInformacionSensor()    β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ Muestra en la vista el nombre,   |
        | modelo y ubicaciΓ³n del sensor    |
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔══════════════════════════════════════╗
    β•‘ PASO 2: configurarEstadoInicial()    β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ Desmarca los checkbox          β”‚
        β”‚ Actualiza grΓ‘fico = vacΓ­o      β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔══════════════════════════════════════════╗
    β•‘ PASO 3: iniciarActualizacionAutomatica() β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ timeline = new Timeline(             β”‚
        β”‚   new KeyFrame(                      β”‚
        β”‚     Duration.millis(500),            β”‚
        β”‚     event -> cicloActualizacion()    β”‚
        β”‚   )                                  β”‚
        β”‚ )                                    β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ timeline.setCycleCount(              β”‚
        β”‚   Animation.INDEFINITE)              β”‚
        β”‚ (Repetir infinitamente)              β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ timeline.play()                      β”‚
        β”‚ (Iniciar temporizador)               β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ AplicaciΓ³n LISTA                     β”‚
        β”‚ Timeline ejecuta cicloActualizacion()| 
        | cada 0.5s                            β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

5.2. CICLO PRINCIPAL - MΓ©todo cicloActualizacion()

Diagrama de Flujo Completo del Ciclo:

    ╔═════════════════════════════════════════════════════╗
    β•‘  Timeline ejecuta cicloActualizacion() cada 500ms   β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                      β”‚
                      ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ cicloActualizacion()                β”‚
        β”‚ (Orquestador del ciclo)             β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔════════════════════════════════════╗
    β•‘ FASE 1: generarNuevaLectura()      β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ modelo.generarLectura()              β”‚
        β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
        β”‚ β”‚ β€’ Variaciones aleatorias         β”‚ β”‚
        β”‚ β”‚ β€’ Picos ocasionales              β”‚ β”‚
        β”‚ β”‚ β€’ Actualizar timestamp           β”‚ β”‚
        β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔══════════════════════════════════════════╗
    β•‘ FASE 2: actualizarValoresMostrados()     β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ actualiza en el card de los valores  |
        | actuales los nuevos valores leido y  |
        | la hora de la lectura                |
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔═════════════════════════════════════╗
    β•‘ FASE 3: agregarPuntosAlGrafico()    β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
        β”‚ β”‚ AΓ±ade puntos a series habilitadasβ”‚ β”‚
        β”‚ β”‚ Recorta si >200 puntos           β”‚ β”‚
        β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔══════════════════════════════════════════╗
    β•‘ FASE 4: actualizarEjeX()                 β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ Establece los limites superior e     |
        | inferior del grΓ‘fico                 |
        | (Ventana deslizante)                 β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   ↓
    ╔══════════════════════════════════════════╗
    β•‘ FASE 5: actualizarAvisos()               β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                   β”‚
                   ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ Usuario ve interfaz actualizada:     β”‚
        β”‚ βœ“ Nuevos valores numΓ©ricos           β”‚
        β”‚ βœ“ GrΓ‘fico con nuevo punto            β”‚
        β”‚ βœ“ Ejes ajustados                     β”‚
        β”‚ βœ“ Avisos actualizados                β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β”‚ (Esperar 500ms)
                   β”‚
                   └──────→ (volver a cicloActualizacion())

5.2.1. Fase 1: Generar Nueva Lectura

    /**
     * Solicita al modelo generar una nueva lectura del sensor.
     * Delega completamente la lΓ³gica al modelo.
     */

5.2.2. Fase 2: Actualizar Valores Mostrados

    /**
     * Actualiza los valores numΓ©ricos mostrados en la card de valores actuales.
     * Obtiene valores formateados del modelo y los asigna a los labels.
     */

5.2.3. Fase 3: Agregar Puntos al GrΓ‘fico

    /**
     * Agrega nuevos puntos a las series del grΓ‘fico.
     * Solo aΓ±ade a series cuyo checkbox estΓ‘ marcado.
     */

5.2.4. Fase 4: Actualizar Eje X

    /**
     * Actualiza los lΓ­mites del eje X para crear efecto ventana deslizante.
     * Delega cΓ‘lculos al modelo.
     */

5.3. Fase 5: Actualizar Avisos - DETALLADO

Diagrama de Flujo Completo:

        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ actualizarAvisos()        β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ Eliminar avisos antiguos    β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  ↓
    ╔═══════════════════════════════════════╗
    β•‘ VALIDACIΓ“N TEMPERATURA                β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                    β”‚
                    ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ ΒΏhayAlertaTemperatura()?     β”‚
        β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             SÍ─      β”‚ NO
               β”‚      |
               ↓      └─────────────┐
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
   β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
   β”‚ β”‚ Crea Label con:          β”‚ β”‚ β”‚
   β”‚ β”‚ β€’ Icono ⚠               β”‚ β”‚ β”‚
   β”‚ β”‚ β€’ Texto formateado       β”‚ β”‚ β”‚
   β”‚ β”‚ β€’ StyleClass "warn-pill" β”‚ β”‚ β”‚
   β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
              β”‚                     β”‚
              ↓                     β”‚
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
   β”‚ aΓ±adir alerta a la card      β”‚ β”‚
   | de avisos                    β”‚ β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
              β”‚                     β”‚
              └────→ β”Œ ← ← ← ← ← ←  β”˜
                     β”‚
                     ↓
    ╔═══════════════════════════════════════╗
    β•‘ VALIDACIΓ“N RESTO DE SENSORES          β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                    β”‚
                    ↓
    ╔═══════════════════════════════════════╗
    β•‘ VERIFICACIΓ“N FINAL                    β•‘
    β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•¦β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
                    β”‚
                    ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ ΒΏHay al menos UNA alerta?           β”‚
        β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             NO─      β”‚ SI
               β”‚      |
               ↓      └─────────────┐
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
   β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
   β”‚ β”‚ Crea Label con:          β”‚ β”‚ β”‚
   β”‚ β”‚ β€’ Texto "Sin avisos"     β”‚ β”‚ β”‚
   β”‚ β”‚ β€’ StyleClass "ok-pill"   β”‚ β”‚ β”‚
   β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚         
              β”‚                     β”‚
              └─────→ β”Œ ← ← ← ← ← ← β”˜
                      β”‚
                      ↓
                    (FIN)

05_Eventos

πŸŽ›οΈ CONTROLADOR - EVENTOS Y CLASE PRINCIPAL

5.9. MANEJADORES DE EVENTOS DE USUARIO

Evento 1: refrescarSeries()

Invocado por:Β CheckBox (cbTemp, cbHum, cbPres) cuando cambia su estado

Nota importante:Β Al desmarcar un checkbox, la serie se oculta pero NO pierde sus datos. Al volver a marcar, recupera todo el historial.


Evento 2: resetChart()

Invocado por:Β Button "Reset"


Evento 3: cerrarApp()

Invocado por: MenuItem "Cerrar" del menΓΊ Archivo