monitor_de_clima_sqlite
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Próxima revisión | Revisión previa | ||
| monitor_de_clima_sqlite [2026/09/07 18:00] – creado hispa | monitor_de_clima_sqlite [2026/09/08 16:30] (actual) – hispa | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| + | <WRAP round box> | ||
| + | ====== Monitor de Clima SQLite ====== | ||
| + | </ | ||
| + | <WRAP tabs> | ||
| + | * [[Estación meteorológica ESP8266 (D1 Mini), con captación de datos y elaboración de gráficos]] | ||
| + | * [[Informática y cacharreo]] | ||
| + | </ | ||
| + | <WRAP collarge> | ||
| + | ==== Introducción y Propósito General ==== | ||
| + | Monitor de Clima SQLite es una aplicación de escritorio desarrollada en Lazarus utilizando la Lazarus Component Library (LCL). Su objetivo principal es servir como una herramienta de visualización y análisis de datos meteorológicos almacenados en bases de datos SQLite locales. El sistema genera de manera dinámica toda su interfaz gráfica en tiempo de ejecución, conectándose a bases de datos relacionales para procesar series temporales y representarlas mediante múltiples gráficos de líneas sincronizados. | ||
| + | |||
| + | </ | ||
| + | < | ||
| + | ==== Código ==== | ||
| + | |||
| + | <code delphi> | ||
| + | unit Unit1; | ||
| + | |||
| + | {$mode objfpc}{$H+} | ||
| + | |||
| + | interface | ||
| + | |||
| + | uses | ||
| + | Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, | ||
| + | SQLite3Conn, | ||
| + | |||
| + | type | ||
| + | TMedicionRecord = record | ||
| + | Fecha: TDateTime; | ||
| + | Temp: Double; | ||
| + | Hum: Double; | ||
| + | Pres: Double; | ||
| + | end; | ||
| + | |||
| + | { TForm1 } | ||
| + | TForm1 = class(TForm) | ||
| + | private | ||
| + | BtnSeleccionarDB: | ||
| + | RadioOpciones: | ||
| + | OpenDialog1: | ||
| + | ChartTemp, | ||
| + | ChartHum, | ||
| + | ChartPres: TChart; | ||
| + | DateSourceTemp, | ||
| + | DateSourceHum, | ||
| + | DateSourcePres: | ||
| + | SQLite3Connection1: | ||
| + | SQLTransaction1: | ||
| + | SQLQuery1: TSQLQuery; | ||
| + | RutaBD: string; | ||
| + | SerieTemp, | ||
| + | SerieHum, | ||
| + | SeriePresion: | ||
| + | Inicializado: | ||
| + | DatosMediciones: | ||
| + | MaxFechaDataset: | ||
| + | TempMax, TempMin, | ||
| + | HumMax, HumMin, | ||
| + | PresMax, PresMin: Double; | ||
| + | TempMaxFecha, | ||
| + | HumMaxFecha, | ||
| + | PresMaxFecha, | ||
| + | |||
| + | procedure BtnSeleccionarDBClick(Sender: | ||
| + | procedure RadioOpcionesClick(Sender: | ||
| + | procedure CargarYGraficar; | ||
| + | |||
| + | procedure CrearInterfazDinamica; | ||
| + | procedure ConfigurarConexion; | ||
| + | procedure ConfigurarGraficas; | ||
| + | |||
| + | procedure ConfigurarEjeHora( | ||
| + | Chart: TChart; | ||
| + | DateSource: TDateTimeIntervalChartSource | ||
| + | ); | ||
| + | |||
| + | procedure AxisGetMarkText( | ||
| + | Sender: TObject; | ||
| + | var AText: String; | ||
| + | AMark: Double | ||
| + | ); | ||
| + | |||
| + | procedure FormResize(Sender: | ||
| + | procedure ActualizarGraficosYEstadisticas; | ||
| + | |||
| + | protected | ||
| + | procedure DoShow; override; | ||
| + | |||
| + | public | ||
| + | end; | ||
| + | |||
| + | var | ||
| + | Form1: TForm1; | ||
| + | |||
| + | implementation | ||
| + | |||
| + | {$R *.lfm} | ||
| + | |||
| + | { ========================================================= } | ||
| + | { | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.DoShow; | ||
| + | begin | ||
| + | inherited DoShow; | ||
| + | |||
| + | if not Inicializado then | ||
| + | begin | ||
| + | Inicializado := True; | ||
| + | |||
| + | { 1. Crear controles y establecer las dimensiones iniciales } | ||
| + | CrearInterfazDinamica; | ||
| + | ConfigurarConexion; | ||
| + | ConfigurarGraficas; | ||
| + | |||
| + | { 2. Mover al monitor principal DESPUÉS de definir las dimensiones } | ||
| + | Self.Position := poDesigned; | ||
| + | Self.Left := Screen.PrimaryMonitor.Left + ((Screen.PrimaryMonitor.Width - Self.Width) div 2); | ||
| + | Self.Top := Screen.PrimaryMonitor.Top + ((Screen.PrimaryMonitor.Height - Self.Height) div 2); | ||
| + | |||
| + | { 3. Configurar eventos y redimensionar } | ||
| + | Self.OnResize := @FormResize; | ||
| + | FormResize(Self); | ||
| + | end; | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { CREAR INTERFAZ | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.CrearInterfazDinamica; | ||
| + | begin | ||
| + | Self.Caption := ' | ||
| + | Self.SetBounds(100, | ||
| + | |||
| + | { Botón seleccionar BD } | ||
| + | BtnSeleccionarDB := TButton.Create(Self); | ||
| + | BtnSeleccionarDB.Parent := Self; | ||
| + | BtnSeleccionarDB.SetBounds(0, | ||
| + | BtnSeleccionarDB.Caption := ' | ||
| + | BtnSeleccionarDB.OnClick := @BtnSeleccionarDBClick; | ||
| + | |||
| + | { Control Radio (TRadioGroup) para el rango } | ||
| + | RadioOpciones := TRadioGroup.Create(Self); | ||
| + | RadioOpciones.Parent := Self; | ||
| + | RadioOpciones.SetBounds(0, | ||
| + | RadioOpciones.Caption := 'Rango de visualización'; | ||
| + | RadioOpciones.Items.Add(' | ||
| + | RadioOpciones.Items.Add(' | ||
| + | RadioOpciones.Columns := 2; | ||
| + | RadioOpciones.ItemIndex := 0; | ||
| + | RadioOpciones.OnClick := @RadioOpcionesClick; | ||
| + | |||
| + | { Diálogo de archivos } | ||
| + | OpenDialog1 := TOpenDialog.Create(Self); | ||
| + | OpenDialog1.Filter := ' | ||
| + | ' | ||
| + | 'Todos los archivos (*.*)|*.*'; | ||
| + | |||
| + | { Gráficas } | ||
| + | ChartTemp := TChart.Create(Self); | ||
| + | ChartTemp.Parent := Self; | ||
| + | |||
| + | ChartHum := TChart.Create(Self); | ||
| + | ChartHum.Parent := Self; | ||
| + | |||
| + | ChartPres := TChart.Create(Self); | ||
| + | ChartPres.Parent := Self; | ||
| + | |||
| + | { Fuentes de fechas } | ||
| + | DateSourceTemp := TDateTimeIntervalChartSource.Create(Self); | ||
| + | DateSourceHum := TDateTimeIntervalChartSource.Create(Self); | ||
| + | DateSourcePres := TDateTimeIntervalChartSource.Create(Self); | ||
| + | |||
| + | { SQLite } | ||
| + | SQLite3Connection1 := TSQLite3Connection.Create(Self); | ||
| + | SQLTransaction1 := TSQLTransaction.Create(Self); | ||
| + | SQLQuery1 := TSQLQuery.Create(Self); | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.RadioOpcionesClick(Sender: | ||
| + | begin | ||
| + | ActualizarGraficosYEstadisticas; | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.ActualizarGraficosYEstadisticas; | ||
| + | var | ||
| + | i: Integer; | ||
| + | FiltroFechaMin: | ||
| + | HayTemp, HayHum, HayPres: Boolean; | ||
| + | TVal, HVal, PVal: Double; | ||
| + | FechaVal: TDateTime; | ||
| + | begin | ||
| + | if Length(DatosMediciones) = 0 then | ||
| + | Exit; | ||
| + | |||
| + | SerieTemp.Clear; | ||
| + | SerieHum.Clear; | ||
| + | SeriePresion.Clear; | ||
| + | |||
| + | HayTemp := False; | ||
| + | HayHum := False; | ||
| + | HayPres := False; | ||
| + | |||
| + | if RadioOpciones.ItemIndex = 1 then | ||
| + | FiltroFechaMin := MaxFechaDataset - 1.0 | ||
| + | else | ||
| + | FiltroFechaMin := 0; | ||
| + | |||
| + | for i := 0 to High(DatosMediciones) do | ||
| + | begin | ||
| + | FechaVal := DatosMediciones[i].Fecha; | ||
| + | |||
| + | if (RadioOpciones.ItemIndex = 0) or (FechaVal >= FiltroFechaMin) then | ||
| + | begin | ||
| + | TVal := DatosMediciones[i].Temp; | ||
| + | HVal := DatosMediciones[i].Hum; | ||
| + | PVal := DatosMediciones[i].Pres; | ||
| + | |||
| + | SerieTemp.AddXY(FechaVal, | ||
| + | SerieHum.AddXY(FechaVal, | ||
| + | SeriePresion.AddXY(FechaVal, | ||
| + | |||
| + | { Temperatura Máx y Mín } | ||
| + | if not HayTemp then | ||
| + | begin | ||
| + | TempMax := TVal; TempMin := TVal; | ||
| + | TempMaxFecha := FechaVal; TempMinFecha := FechaVal; | ||
| + | HayTemp := True; | ||
| + | end | ||
| + | else | ||
| + | begin | ||
| + | if TVal > TempMax then begin TempMax := TVal; TempMaxFecha := FechaVal; end; | ||
| + | if TVal < TempMin then begin TempMin := TVal; TempMinFecha := FechaVal; end; | ||
| + | end; | ||
| + | |||
| + | { Humedad Máx y Mín } | ||
| + | if not HayHum then | ||
| + | begin | ||
| + | HumMax := HVal; HumMin := HVal; | ||
| + | HumMaxFecha := FechaVal; HumMinFecha := FechaVal; | ||
| + | HayHum := True; | ||
| + | end | ||
| + | else | ||
| + | begin | ||
| + | if HVal > HumMax then begin HumMax := HVal; HumMaxFecha := FechaVal; end; | ||
| + | if HVal < HumMin then begin HumMin := HVal; HumMinFecha := FechaVal; end; | ||
| + | end; | ||
| + | |||
| + | { Presión Máx y Mín } | ||
| + | if not HayPres then | ||
| + | begin | ||
| + | PresMax := PVal; PresMin := PVal; | ||
| + | PresMaxFecha := FechaVal; PresMinFecha := FechaVal; | ||
| + | HayPres := True; | ||
| + | end | ||
| + | else | ||
| + | begin | ||
| + | if PVal > PresMax then begin PresMax := PVal; PresMaxFecha := FechaVal; end; | ||
| + | if PVal < PresMin then begin PresMin := PVal; PresMinFecha := FechaVal; end; | ||
| + | end; | ||
| + | end; | ||
| + | end; | ||
| + | |||
| + | { | ||
| + | FORMATO ESTANDARIZADO DE LEYENDA (Uso de %% para imprimir el carácter % en Format) | ||
| + | Línea 1: Titular igualado a 20 caracteres visibles exactos. | ||
| + | Línea 2 y 3: Mismo formato de ancho fijo (%7.2f). | ||
| + | } | ||
| + | if HayTemp then | ||
| + | SerieTemp.Title := Format(' | ||
| + | ' Máx: %7.2f (%s)' + LineEnding + | ||
| + | ' Mín: %7.2f (%s)', | ||
| + | [TempMax, FormatDateTime(' | ||
| + | | ||
| + | else | ||
| + | SerieTemp.Title := ' | ||
| + | |||
| + | if HayHum then | ||
| + | SerieHum.Title := Format(' | ||
| + | ' | ||
| + | ' | ||
| + | | ||
| + | HumMin, FormatDateTime(' | ||
| + | else | ||
| + | SerieHum.Title := ' | ||
| + | |||
| + | if HayPres then | ||
| + | SeriePresion.Title := Format(' | ||
| + | ' Máx: %7.2f (%s)' + LineEnding + | ||
| + | ' Mín: %7.2f (%s)', | ||
| + | [PresMax, FormatDateTime(' | ||
| + | | ||
| + | else | ||
| + | SeriePresion.Title := ' | ||
| + | |||
| + | ChartTemp.Invalidate; | ||
| + | ChartHum.Invalidate; | ||
| + | ChartPres.Invalidate; | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.FormResize(Sender: | ||
| + | var | ||
| + | AltoDisponible, | ||
| + | AnchoTotalPanel, | ||
| + | begin | ||
| + | MargenTop := 65; | ||
| + | |||
| + | { 1. Centrar Botón y RadioGroup en la parte superior } | ||
| + | EspacioEntreControles := 20; | ||
| + | AnchoTotalPanel := BtnSeleccionarDB.Width + EspacioEntreControles + RadioOpciones.Width; | ||
| + | PosInicioPanel := (Self.ClientWidth - AnchoTotalPanel) div 2; | ||
| + | |||
| + | if PosInicioPanel < 10 then | ||
| + | PosInicioPanel := 10; | ||
| + | |||
| + | BtnSeleccionarDB.Left := PosInicioPanel; | ||
| + | BtnSeleccionarDB.Top := 10; | ||
| + | |||
| + | RadioOpciones.Left := PosInicioPanel + BtnSeleccionarDB.Width + EspacioEntreControles; | ||
| + | RadioOpciones.Top := 2; | ||
| + | |||
| + | { 2. Calcular espacio para los gráficos } | ||
| + | AltoDisponible := Self.ClientHeight - MargenTop - 10; | ||
| + | |||
| + | if AltoDisponible < 300 then | ||
| + | Exit; | ||
| + | |||
| + | AltoGrafico := AltoDisponible div 3; | ||
| + | AnchoGrafica := Self.ClientWidth - 20; | ||
| + | |||
| + | if AnchoGrafica < 300 then | ||
| + | AnchoGrafica := 300; | ||
| + | |||
| + | ChartTemp.SetBounds(10, | ||
| + | ChartHum.SetBounds(10, | ||
| + | ChartPres.SetBounds(10, | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.ConfigurarConexion; | ||
| + | begin | ||
| + | SQLTransaction1.DataBase := SQLite3Connection1; | ||
| + | SQLQuery1.DataBase := SQLite3Connection1; | ||
| + | SQLQuery1.Transaction := SQLTransaction1; | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.AxisGetMarkText( | ||
| + | Sender: TObject; | ||
| + | var AText: String; | ||
| + | AMark: Double | ||
| + | ); | ||
| + | begin | ||
| + | AText := FormatDateTime(' | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { EJE DE TIEMPO | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.ConfigurarEjeHora( | ||
| + | Chart: TChart; | ||
| + | DateSource: TDateTimeIntervalChartSource | ||
| + | ); | ||
| + | begin | ||
| + | DateSource.DateTimeFormat := ' | ||
| + | DateSource.Params.MaxLength := 80; | ||
| + | DateSource.Params.MinLength := 20; | ||
| + | |||
| + | Chart.BottomAxis.Marks.Source := DateSource; | ||
| + | Chart.BottomAxis.Marks.Style := smsLabel; | ||
| + | Chart.BottomAxis.OnGetMarkText := @AxisGetMarkText; | ||
| + | Chart.BottomAxis.Marks.LabelFont.Orientation := 900; | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { CONFIGURAR GRÁFICAS | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.ConfigurarGraficas; | ||
| + | begin | ||
| + | ConfigurarEjeHora(ChartTemp, | ||
| + | ConfigurarEjeHora(ChartHum, | ||
| + | ConfigurarEjeHora(ChartPres, | ||
| + | |||
| + | { Temperatura } | ||
| + | ChartTemp.ClearSeries; | ||
| + | ChartTemp.Title.Text.Text := ' | ||
| + | ChartTemp.Title.Visible := True; | ||
| + | ChartTemp.Legend.Visible := True; | ||
| + | ChartTemp.Legend.Font.Name := ' | ||
| + | ChartTemp.Margins.Top := 10; | ||
| + | ChartTemp.Margins.Bottom := 10; | ||
| + | |||
| + | SerieTemp := TLineSeries.Create(ChartTemp); | ||
| + | SerieTemp.SeriesColor := clRed; | ||
| + | SerieTemp.LinePen.Width := 3; | ||
| + | ChartTemp.AddSeries(SerieTemp); | ||
| + | |||
| + | { Humedad } | ||
| + | ChartHum.ClearSeries; | ||
| + | ChartHum.Title.Text.Text := ' | ||
| + | ChartHum.Title.Visible := True; | ||
| + | ChartHum.Legend.Visible := True; | ||
| + | ChartHum.Legend.Font.Name := ' | ||
| + | ChartHum.Margins.Top := 10; | ||
| + | ChartHum.Margins.Bottom := 10; | ||
| + | |||
| + | SerieHum := TLineSeries.Create(ChartHum); | ||
| + | SerieHum.SeriesColor := clBlue; | ||
| + | SerieHum.LinePen.Width := 3; | ||
| + | ChartHum.AddSeries(SerieHum); | ||
| + | |||
| + | { Presión } | ||
| + | ChartPres.ClearSeries; | ||
| + | ChartPres.Title.Text.Text := ' | ||
| + | ChartPres.Title.Visible := True; | ||
| + | ChartPres.Legend.Visible := True; | ||
| + | ChartPres.Legend.Font.Name := ' | ||
| + | ChartPres.Margins.Top := 10; | ||
| + | ChartPres.Margins.Bottom := 10; | ||
| + | |||
| + | SeriePresion := TLineSeries.Create(ChartPres); | ||
| + | SeriePresion.SeriesColor := clGreen; | ||
| + | SeriePresion.LinePen.Width := 3; | ||
| + | ChartPres.AddSeries(SeriePresion); | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.BtnSeleccionarDBClick(Sender: | ||
| + | begin | ||
| + | if OpenDialog1.Execute then | ||
| + | begin | ||
| + | RutaBD := OpenDialog1.FileName; | ||
| + | CargarYGraficar; | ||
| + | end; | ||
| + | end; | ||
| + | |||
| + | { ========================================================= } | ||
| + | { CARGAR Y GRAFICAR DATOS } | ||
| + | { ========================================================= } | ||
| + | |||
| + | procedure TForm1.CargarYGraficar; | ||
| + | var | ||
| + | HoraVal: TDateTime; | ||
| + | StrFecha: string; | ||
| + | Temp, Hum, Pres: Double; | ||
| + | FS: TFormatSettings; | ||
| + | Count: Integer; | ||
| + | begin | ||
| + | if not FileExists(RutaBD) then | ||
| + | begin | ||
| + | ShowMessage(' | ||
| + | Exit; | ||
| + | end; | ||
| + | |||
| + | FS := DefaultFormatSettings; | ||
| + | FS.DateSeparator := ' | ||
| + | FS.TimeSeparator := ':'; | ||
| + | FS.ShortDateFormat := ' | ||
| + | FS.LongTimeFormat := ' | ||
| + | |||
| + | try | ||
| + | SQLite3Connection1.DatabaseName := RutaBD; | ||
| + | SQLite3Connection1.Connected := True; | ||
| + | SQLTransaction1.StartTransaction; | ||
| + | |||
| + | SQLQuery1.SQL.Text := | ||
| + | ' | ||
| + | 'FROM mediciones ' + | ||
| + | 'ORDER BY id ASC'; | ||
| + | SQLQuery1.Open; | ||
| + | |||
| + | Count := 0; | ||
| + | SetLength(DatosMediciones, | ||
| + | |||
| + | while not SQLQuery1.EOF do | ||
| + | begin | ||
| + | StrFecha := SQLQuery1.FieldByName(' | ||
| + | |||
| + | if not TryStrToDateTime(StrFecha, | ||
| + | TryStrToDateTime(StrFecha, | ||
| + | |||
| + | Temp := SQLQuery1.FieldByName(' | ||
| + | Hum := SQLQuery1.FieldByName(' | ||
| + | Pres := SQLQuery1.FieldByName(' | ||
| + | |||
| + | SetLength(DatosMediciones, | ||
| + | DatosMediciones[Count].Fecha := HoraVal; | ||
| + | DatosMediciones[Count].Temp := Temp; | ||
| + | DatosMediciones[Count].Hum := Hum; | ||
| + | DatosMediciones[Count].Pres := Pres; | ||
| + | |||
| + | Inc(Count); | ||
| + | SQLQuery1.Next; | ||
| + | end; | ||
| + | |||
| + | if Count > 0 then | ||
| + | MaxFechaDataset := DatosMediciones[Count - 1].Fecha; | ||
| + | |||
| + | SQLQuery1.Close; | ||
| + | SQLTransaction1.Commit; | ||
| + | SQLite3Connection1.Connected := False; | ||
| + | |||
| + | ActualizarGraficosYEstadisticas; | ||
| + | |||
| + | except | ||
| + | on E: Exception do | ||
| + | begin | ||
| + | ShowMessage(' | ||
| + | if SQLTransaction1.Active then | ||
| + | SQLTransaction1.Rollback; | ||
| + | if SQLite3Connection1.Connected then | ||
| + | SQLite3Connection1.Connected := False; | ||
| + | end; | ||
| + | end; | ||
| + | end; | ||
| + | |||
| + | end. | ||
| + | </ | ||
| + | </ | ||
| + | <WRAP collarge> | ||
| + | ==== Estructura de Datos y Clases Principales ==== | ||
| + | |||
| + | - **TMedicionRecord**: | ||
| + | - **TForm1**: La clase central del programa que hereda de TForm. Encapsula la lógica de los controles visuales creados por código, los componentes de conectividad a bases de datos, los algoritmos de filtrado temporal, el redimensionamiento responsivo y el renderizado gráfico. | ||
| + | |||
| + | === TForm1 === | ||
| + | |||
| + | == Componentes y Variables Privadas == | ||
| + | |||
| + | **Controles de Interfaz:** | ||
| + | |||
| + | * **BtnSeleccionarDB**: | ||
| + | * **RadioOpciones**: | ||
| + | * **OpenDialog1**: | ||
| + | * **ChartTemp, | ||
| + | * **LabelTempMaxMin, | ||
| + | |||
| + | **Subsistema de Base de Datos:** | ||
| + | |||
| + | * SQLite3Connection1: | ||
| + | * SQLTransaction1: | ||
| + | * SQLQuery1: Objeto ejecutor de consultas SQL para la extracción de registros. | ||
| + | |||
| + | **Estado y Almacenamiento: | ||
| + | |||
| + | * **RutaBD**: Cadena de texto que almacena la ruta del archivo de base de datos seleccionado. | ||
| + | * **DatosMediciones**: | ||
| + | * **MaxFechaDataset**: | ||
| + | * **TempMax, TempMin, HumMax, HumMin, PresMax, PresMin**: Variables de doble precisión que almacenan los extremos numéricos calculados en tiempo real. | ||
| + | * **Inicializado**: | ||
| + | |||
| + | == Métodos y Procedimientos Funcionales == | ||
| + | |||
| + | **Ciclo de Vida y Configuración Inicial** | ||
| + | |||
| + | * **DoShow; override**: Método protegido heredado de TForm que se ejecuta de manera segura cuando el formulario se hace visible por primera vez. Invoca la creación de la interfaz, centra la ventana en el monitor principal y activa el evento de redimensionamiento. | ||
| + | * **CrearInterfazDinamica**: | ||
| + | * **ConfigurarConexion**: | ||
| + | * **ConfigurarGraficas**: | ||
| + | * **CrearEtiquetasMaxMin**: | ||
| + | |||
| + | **Gestión de Datos y Conectividad** | ||
| + | |||
| + | * **BtnSeleccionarDBClick(Sender: | ||
| + | * **CargarYGraficar**: | ||
| + | * **ActualizarGraficosYEstadisticas**: | ||
| + | |||
| + | **Representación Temporal y Ejes** | ||
| + | |||
| + | * **ConfigurarEjeHora(Chart: | ||
| + | * **AxisGetMarkText(Sender: | ||
| + | |||
| + | **Diseño Responsivo y Eventos de Usuario** | ||
| + | |||
| + | * **FormResize(Sender: | ||
| + | * **RadioOpcionesClick(Sender: | ||
| + | </ | ||
| + | |||
| + | {{tag> informática_y_cacharreo Pascal FreePascal Lazarus}} | ||
