Creación de Demo#

La creación de un reporte comienza con el desarrollo de un reporte demo (prototipo). Este prototipo tiene como objetivo mostrar la idea de funcionamiento y demostrar las funcionalidades del reporte al cliente. Esto permite recibir retroalimentación y realizar mejoras en el aspecto visual del reporte y la forma de presentar la información.

Una vez que se cuenta con la demo, la integración del script se simplifica, ya que resulta más fácil comprender qué datos se van a utilizar y cómo deben presentarse.

Nota

Recuerde que para el desarrollo de un reporte puede realizar el proceso de configuración en Producción o en Preproducción , ya que el proceso es idéntico. Sin embargo, se recomienda iniciar el proceso de creación de reportes en preproducción. Una vez finalizado y seguro de sus cambios, puede transferirlo a producción.

Estructura de archivos#

Dentro del Repositorio servido encontrará los archivos correspondientes al front-end del reporte. Por favor, sigan los siguientes pasos para crear los archivos necesarios y continúe revisando cada sección correspondiente a la explicación sobre su contenido.

  1. Cree una carpeta exclusiva dentro de la carpeta Apps para sus reportes en caso de no contar con una.

Nota

Identifique a la carpeta con el nombre de su empresa o el cliente que lo requiera.

  1. Cree los cuatro archivos correspondientes al front-end del reporte, las cuales incluyen:

  • reporte_nombre.html: Estructura del reporte.

  • reporte_nombre.js: Lógica encargada de gestionar las solicitudes a la API, así como de procesar y presentar la información correspondiente en la estructura establecida.

  • reporte_nombre_data.js: Configuraciones de librerías que se utilizan.

  • style.css: Estilos generales del reporte (un archivo por carpeta).

Importante

En las siguientes secciones se explicará el contenido de cada archivo. Sin embargo, considere que NO se tiene un estándar establecido para el contenido. No obstante, utilice los ejemplos como base para sus proyectos futuros.

Estructura html#

El archivo html se encarga de establecer la estructura del reporte y facilitar la inclusión de archivos y bibliotecas externas que son necesarias. El archivo HTML se divide en tres partes: el head, el body y las librerías.

A continuación, se presentan fragmentos de código HTML con explicaciones detalladas sobre cada parte, destacando los elementos que se pueden personalizar.

Nota

El código completo se encuentra al final de la sección.

body#

En el cuerpo (body) se establece la estructura visible del reporte, donde se definen elementos como cabeceras, títulos, gráficas, tablas, cards, entre otros. Se incluye todo lo necesario para establecer la estructura correspondiente a filtros y elementos donde la información se presentará.

En el siguiente dropdown, encontrará el código del cuerpo de un reporte.

Código body
  1<body>
  2    <!-- Header -->
  3    <nav class="navbar header">
  4        <div class="navbar-brand">
  5            <div class="row">
  6                <div class="col-md-6">
  7                    <a href="index.html">
  8                        <div class="logo_marca">
  9                            <img src="https://app.linkaform.com/img/login-linkaform-logo.png" alt="LinkaForm" id="image_log">
 10                        </div>
 11                    </a>
 12                </div>
 13                <div class="col-md-6">
 14                    <div class="container">
 15                        <div class="back"  id="atras"><i class="fa fa-solid fa-arrow-left"></i>Atras</div>
 16                        <div class="close" id="close_sesion"><a onclick="closeSession();"><i class="fa-solid fa-lock"></i>Cerrar Sesión</a></div>
 17                    </div>
 18                </div>
 19            </div>
 20            <div class="col-md-12">
 21                <h1 id="title_report">Reporte Visitas</h1>
 22            </div>
 23        </div>
 24    </nav>
 25
 26    <!-- Loading style -->
 27    <div class="loading-container">
 28        <div class="spinner-border text-primary" role="status">
 29            <span class="sr-only">Loading...</span>
 30        </div>
 31    </div>
 32
 33    <!-- Content -->
 34    <div style="width:100%">
 35        <div class="app" id="appCont" style="padding-top: 0px;">
 36
 37            <!--Session -->
 38            <div class="row inicio_ses" id="inicio_ses">
 39                <div class="errorLogin" id="errorLog"></div>
 40                <div class="control">
 41                    <div class="renglon">
 42                        <h3>Usuario: </h3>
 43                        <input class="form-control ds-input" id="user" name="user" value="">
 44                    </div>
 45                    <div class="renglon">
 46                        <h3>Contraseña: </h3>
 47                        <input class="form-control ds-input" type="password" id="pass" name="pass" value="">
 48                    </div>
 49                    <div class="controlBtn">
 50                    <div class="btn btn-primary" onclick="login()">Login</div>
 51                    <div class="btn btn-primary" onclick="reset()">Reset</div>
 52                    </div>
 53                </div>
 54            </div>
 55
 56            <!--Title Demo -->
 57            <div id="title_demo" style="margin-bottom: 20px;">
 58                <center>
 59                    <h1><span>Demo data</span>&nbsp;&nbsp;</h1>
 60                </center>
 61            </div>
 62
 63            <!--Options FIlter -->
 64            <div class="col-sm-12 col-md-12 col-lg-12 row" id="divOptions">
 65                <button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#firstParameters" aria-expanded="false" aria-controls="collapseExample" id="buttonFilter">
 66                    <i class="fa-solid fa-filter"></i>
 67                </button >  &nbsp;  &nbsp;
 68                <div class="btn btn-primary" onclick="runFirstElement()" >Run</div>
 69            </div>
 70
 71            <!--Filters -->
 72            <div id="firstParameters" class="collapse row show">
 73                <div class="col-sm-12 col-md-3 col-lg-3">
 74                    <h5>Fecha Desde: </h5>
 75                    <input class="form-control ds-input" type="date" id="date_from" name="date_from">
 76                </div>
 77                <div class="col-sm-12 col-md-3 col-lg-3">
 78                    <h5>Fecha Hasta: </h5>
 79                    <input class="form-control ds-input" type="date" id="date_to" name="date_to">
 80                </div>
 81
 82                <div class="col-sm-12 col-md-3 col-lg-3" >
 83                    <h5>Promotor: </h5>
 84                    <select class="form-control mdb-select md-form" id="promotor">
 85                        <option value="">--Seleccione--</option>
 86                    </select>
 87                </div>
 88            </div>
 89
 90            <!--Content -->
 91            <div class="row" style="margin-top:20px;"  id="divContent">
 92
 93                <!--Primer Elemento -->
 94                <div class="col-sm-12 col-md-12 col-lg-12" style="align-items: center;overflow-y: scroll;">
 95                    <section class="title_tables">
 96                        <h3><span>Recepción Visitas</span>&nbsp;&nbsp;
 97                            <button class="btn btn-primary" id="download_csv_firstElement"><i class="fa-solid fa-file-csv"></i></button>
 98                            <button class="btn btn-success" id="download_xlsx_firstElement"><i class="fa-regular fa-file-excel"></i></button>
 99                        </h3>
100                        <hr class="hrFirstElement">
101                    </section>
102                    <div id="firstElement" ></div>
103                </div>
104            </div>
105        </div>
106    </div>
107</body>

Prudencia

En los elementos, no se recomienda el uso de estilos en línea. En su lugar, se sugiere asignar clases a los elementos y colocar el código CSS correspondiente en la sección de estilos (style) de su proyecto.

A continuación, se detallan por bloques de código el cuerpo del reporte para indicar qué elementos se pueden personalizar.

Header del reporte#

El primer bloque corresponde al encabezado del reporte. Su función principal es mostrar las siguientes opciones:

  • Opción para cerrar sesión.

  • Mostrar logo de la empresa.

Ver también

Consulte la Función window.onload donde se detallan los eventos utilizados.

  • Mostrar nombre del reporte.

Header#
 1<!-- Header -->
 2<nav class="navbar header">
 3    <div class="navbar-brand">
 4        <div class="row">
 5            <!-- Logo -->
 6            <div class="col-md-6">
 7                <a href="index.html">
 8                    <div class="logo_marca">
 9                        <img src="https://app.linkaform.com/img/login-linkaform-logo.png" alt="LinkaForm" id="image_log">
10                    </div>
11                </a>
12            </div>
13
14            <!-- Opción para cerrar sesión -->
15            <div class="col-md-6">
16                <div class="container">
17                    <div class="back"  id="atras"><i class="fa fa-solid fa-arrow-left"></i>Atras</div>
18                    <div class="close" id="close_sesion"><a onclick="closeSession();"><i class="fa-solid fa-lock"></i>Cerrar Sesión</a></div>
19                </div>
20            </div>
21        </div>
22
23        <!-- Nombre del reporte (cambiar) -->
24        <div class="col-md-12">
25            <h1 id="title_report">Nombre del reporte</h1>
26        </div>
27    </div>
28</nav>

Prudencia

Regularmente, la estructura no cambia. Sin embargo, asegúrese de cambiar el nombre del reporte (línea 25). Lea los comentarios en el código.

../../_images/Reportes11.png

Content del reporte#

El contenido (content) es la parte más importante de la estructura html; aquí se establecen los elementos que se utilizan para filtrar y representar la data. Dentro de content, se encuentran bloques de código mayormente estandarizados que se explican a continuación.

Nota

Al final, podrá encontrar el bloque completo del contenido.

El bloque Session contiene el inicio de sesión del reporte, es decir, cuando se intenta abrir desde Servido .

Ver también

Revise la estructura del archivo js, en la función window.onload y lea los comentarios de la línea 36.

 1<!-- Session -->
 2<div class="row inicio_ses" id="inicio_ses">
 3    <div class="errorLogin" id="errorLog"></div>
 4    <!-- Login -->
 5    <div class="control">
 6        <div class="renglon">
 7            <h3>Usuario: </h3>
 8            <input class="form-control ds-input" id="user" name="user" value="">
 9        </div>
10        <div class="renglon">
11            <h3>Contraseña: </h3>
12            <input class="form-control ds-input" type="password" id="pass" name="pass" value="">
13        </div>
14        <!-- Botones -->
15        <div class="controlBtn">
16            <div class="btn btn-primary" onclick="login()">Login</div>
17            <div class="btn btn-primary" onclick="reset()">Reset</div>
18        </div>
19    </div>
20</div>
../../_images/Reportes14.png

El bloque title Demo, es simplemente el título que diferencia al reporte, indicando que es solo un reporte demo.

Ver también

Consulte Local con datos demo .

1<!--Title Demo -->
2<div id="title_demo" style="margin-bottom: 20px;">
3    <center>
4        <h1><span>Demo data</span>&nbsp;&nbsp;</h1>
5    </center>
6</div>
../../_images/Reportes30.png

Options Filter es el botón que permite habilitar u ocultar los filtros disponibles, así como la opción Run para ejecutar la consulta.

1<!--Options FIlter -->
2<div class="col-sm-12 col-md-12 col-lg-12 row" id="divOptions">
3    <button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#firstParameters" aria-expanded="false" aria-controls="collapseExample" id="buttonFilter">
4        <i class="fa-solid fa-filter"></i>
5    </button >  &nbsp;  &nbsp;
6    <div class="btn btn-primary" onclick="runFirstElement()">Run</div>
7</div>
../../_images/Reportes15.png

Atención

Tenga en cuenta que este botón NO funciona si está accediendo con la URL local con datos demo, para ello debe complementar la URL con el id_script. Consulte URLs de acceso .

Filtros#

El contenido Filters son las opciones de filtros para tratar la información, siendo las más comunes las Fechas Desde y Fecha Hasta.

 1<!-- Filters -->
 2<div id="firstParameters" class="collapse row show">
 3    <!-- Filtro uno -->
 4    <div class="col-sm-12 col-md-3 col-lg-3">
 5        <h5>Fecha Desde: </h5>
 6        <input class="form-control ds-input" type="date" id="date_from" name="date_from">
 7    </div>
 8
 9    <!-- Filtro dos -->
10    <div class="col-sm-12 col-md-3 col-lg-3">
11        <h5>Fecha Hasta: </h5>
12        <input class="form-control ds-input" type="date" id="date_to" name="date_to">
13    </div>
14
15    <!-- Filtro tres -->
16    <div class="col-sm-12 col-md-3 col-lg-3" >
17        <h5>Promotor: </h5>
18        <select class="form-control mdb-select md-form" id="promotor">
19            <option value="">--Seleccione--</option>
20        </select>
21    </div>
22</div>
../../_images/Reportes12.png

Modifique los filtros según sus necesidades. Añada o elimine filtros según sea necesario; estos pueden ser filtros de fecha, rango, opciones, etc.

Nota

En el ejemplo anterior, hay una tercera opción de filtro llamada Promotor (líneas 16-21). Solamente asegúrese de asignar un id descriptivo al elemento. El id firstParameters es utilizado para mostrar todos los filtros. Consulte la función window-load para conocer más detalles.

Elementos de representación#

En el bloque Content, se incluyen elementos del reporte como tablas, gráficos, cards, o cualquier otro elemento donde se representará la data.

Atención

  • Todo elemento que se incluya debe estar dentro del contenedor div con la clase row y el id divContent.

  • Independientemente del número de elementos que ocupe dentro del divContent (contenedor de los elementos), asegúrese de que el id de su elemento tenga un orden.

Las tablas son generadas por la biblioteca Tabulator , que permite la creación de tablas interactivas y dinámicas. Existen varios tipos de tablas. En este caso, se muestra la estructura de una tabla con filtros de datos en el encabezado, así como una tabla con filas anidadas.

Advertencia

En los resultados de los siguientes ejemplos se visualiza la estructura completa de las tablas (cómo se verían), sin embargo, la generación de su estructura se realiza en el archivo data.js . Aquí simplemente se establecen títulos, opciones relacionadas con las mismas y se especifica que habrá una tabla.

Tabla con filtro

El siguiente bloque de código corresponde al título de la tabla y las opciones de descarga (csv y xls) de la información de una tabla. Estas funcionalidades son proporcionadas por la biblioteca Tabulator Download Data .

 1<!--Content -->
 2<div class="row" style="margin-top:20px;"  id="divContent">
 3    <!--Primer Elemento -->
 4    <div class="col-sm-12 col-md-12 col-lg-12" style="align-items: center;overflow-y: scroll;">
 5        <section class="title_tables">
 6            <h3><span>Recepción Visitas</span>&nbsp;&nbsp;
 7                <button class="btn btn-primary" id="download_csv_firstElement"><i class="fa-solid fa-file-csv"></i></button>
 8                <button class="btn btn-success" id="download_xlsx_firstElement"><i class="fa-regular fa-file-excel"></i></button>
 9            </h3>
10            <hr class="hrFirstElement">
11        </section>
12        <div id="firstElement" ></div>
13    </div>
14</div>
../../_images/Reportes13.png

Tabla anidada

Del mismo modo, el siguiente bloque de código corresponde al título de la tabla y las opciones de descarga. Observe el atributo id

Advertencia

  • La función de descarga de CSV no admite encabezados de columnas agrupados, grupos de filas o cálculos de columnas, debido a la limitada forma de representar estos en datos CSV.

  • Para descargar los registros de una tabla anidada en un archivo xls, debe expandir todas las filas que desee extraer; de lo contrario, solo podrá descargar el registro del primer nivel.

 1<!--Content -->
 2<div class="row" style="margin-top:20px;"  id="divContent">
 3    <!--Segundo elemento-->
 4    <div class="col-sm-12 col-md-12 col-lg-12" style="align-items: center;overflow-y: scroll;">
 5        <section class="title_tables">
 6            <h3 ><span>Report</span>&nbsp;&nbsp;
 7                <button  class="btn btn-primary" id="download_csv_secondElement"><i class="fa-solid fa-file-csv"></i></button>
 8                <button  class="btn btn-success" id="download_xlsx_secondElement"><i class="fa-regular fa-file-excel"></i></button>
 9            </h3>
10            <hr class="stock-HrsecondElement">
11        </section>
12        <div id="secondElement" > </div>
13    </div>
14</div>
../../_images/Reportes37.png

Atención

Identifique y tenga precaución con el uso del atributo id de los botones (líneas 7-8), ya que son utilizados por la biblioteca Tabulator para poblar con datos.

Los bloques de código anteriores ya se encuentran mayormente estandarizados. Si necesita otra tabla, simplemente copie y pegue, pero asegúrese de colocar el código dentro de la clase row y cambiar el id (Líneas 7, 8, 10, 12) por el número de elemento que ocupe dentro del divContent. Por ejemplo, puede utilizar firstElement, secondElement, thirdElement y así sucesivamente.

Una card (tarjeta) es un elemento visual que presenta información relevante de manera resumida y atractiva en un reporte. La mayoría de los reportes que utilizan tarjetas ya tienen una estructura mayormente estandarizada. Observe los ejemplos.

Atención

  • Asegúrese de colocar el código dentro de la clase row y cambiar los ids necesarios.

  • Si lo requiere, especifique el dato demo directamente en el span correspondiente o en la función necesaria.

  • Para el uso de tarjetas, no es necesario especificar el número de elemento que representa dentro divContent debido a la simplicidad de representar un valor en específico. Es decir, regularmente, una tarjeta representa un solo valor y esta información se puede obtener de datos relacionados, como por ejemplo una tabla. Por lo tanto, realizar otra operación que dará el mismo resultado es innecesario. Dentro del mismo diccionario se puede calcular la información requerida.

Cards

El siguiente bloque de código, podrá observar la estructura de seis tarjetas. Asegúrese de ajustar los títulos y los ids de los títulos y textos. Observe los comentarios dentro del código y el resultado.

 1<!-- Content-->
 2<div class="row" style="margin-top:20px;" id="divContent">
 3    <!-- CARDS PRIMER NIVEL -->
 4    <!-- CARD 1 -->
 5    <div class="col-xs-12 col-md-12 col-lg-4 pr-0 mb-2 div-card">
 6        <div class="card card-stats mb-4 mb-xl-0 rounded-7">
 7            <div class="card-body plan_production_subcard_headerI">
 8                <div class="row">
 9                    <div class="col">
10                        <h6 class="card-title text-uppercase text-dark mb-0" id="titleCard1">Card 1</h6> <!-- Título -->
11                        <span class="h4 font-weight-bold mb-0 text-dark" id="textCard1">0</span> <!-- Texto (modificable) -->
12                    </div>
13                </div>
14            </div>
15        </div>
16    </div>
17    <!-- CARD 2 -->
18    <div class="col-xs-12 col-md-12 col-lg-4 pr-0 mb-2 div-card">
19        <div class="card card-stats mb-4 mb-xl-0 rounded-7">
20            <div class="card-body plan_production_subcard_headerI">
21                <div class="row">
22                    <div class="col">
23                        <h6 class="card-title text-uppercase text-dark mb-0"  id="titleCard2">Card 2</h6> <!-- Título -->
24                        <span class="h4 font-weight-bold mb-0 text-dark" id="textCard2">0</span> <!-- Texto (modificable) -->
25                    </div>
26                </div>
27            </div>
28        </div>
29    </div>
30    <!-- CARD 3 -->
31    <div class="col-xs-12 col-md-12 col-lg-4 pr-0 mb-2 div-card">
32        <div class="card card-stats mb-4 mb-xl-0 rounded-7">
33            <div class="card-body plan_production_subcard_headerI">
34                <div class="row">
35                    <div class="col">
36                        <h6 class="card-title text-uppercase text-dark mb-0"  id="titleCard3">Card 3</h6> <!-- Título -->
37                        <span class="h4 font-weight-bold mb-0 text-dark" id="textCard3">0</span> <!-- Texto (modificable) -->
38                    </div>
39                </div>
40            </div>
41        </div>
42    </div>
43
44    <!-- CARDS SEGUNDO NIVEL -->
45    <!-- CARD 4 -->
46    <div class="col-xs-12 col-md-12 col-lg-4 pr-0 mb-2 div-card">
47        <div class="card card-stats mb-4 mb-xl-0 rounded-7">
48            <div class="card-body plan_production_subcard_headerI">
49                <div class="row">
50                    <div class="col">
51                        <h6 class="card-title text-uppercase text-dark mb-0"  id="titleCard4">Card 4</h6> <!-- Título -->
52                        <span class="h4 font-weight-bold mb-0 text-dark" id="textCard4">0</span> <!-- Texto (modificable) -->
53                    </div>
54                </div>
55            </div>
56        </div>
57    </div>
58    <!-- CARD 5 -->
59    <div class="col-xs-12 col-md-12 col-lg-4 pr-0 mb-2 div-card">
60        <div class="card card-stats mb-4 mb-xl-0 rounded-7">
61            <div class="card-body plan_production_subcard_headerI">
62                <div class="row">
63                    <div class="col">
64                        <h6 class="card-title text-uppercase text-dark mb-0"  id="titleCard5">Card 5</h6> <!-- Título -->
65                        <span class="h4 font-weight-bold mb-0 text-dark" id="textCard5">0</span> <!-- Texto (modificable) -->
66                    </div>
67                </div>
68            </div>
69        </div>
70    </div>
71    <!-- CARD 6 -->
72    <div class="col-xs-12 col-md-12 col-lg-4 pr-0 mb-2 div-card">
73        <div class="card card-stats mb-4 mb-xl-0 rounded-7">
74            <div class="card-body plan_production_subcard_headerI">
75                <div class="row">
76                    <div class="col">
77                        <h6 class="card-title text-uppercase text-dark mb-0"  id="titleCard6">Card 6</h6> <!-- Título -->
78                        <span class="h4 font-weight-bold mb-0 text-dark" id="textCard6">0</span> <!-- Texto (modificable) -->
79                    </div>
80                </div>
81            </div>
82        </div>
83    </div>
84</div>
../../_images/Reportes38.png

Indicador gauge

Un indicador gauge tiene el propósito de mostrar visualmente un valor numérico en relación con un rango específico o un objetivo. Aunque el indicador gauge tiene una apariencia similar a una card, esta utiliza la biblioteca plotly para su funcionamiento.

El siguiente código contiene la estructura de dos tarjetas y un indicador gauge. Revise los comentarios dentro del código.

Atención

Asegúrese de ajustar los títulos, iconos (si los necesita), ids de los títulos y textos. Observe los comentarios dentro del código y el resultado.

 1<div class="row" style="margin-top:20px;" id="divContent">
 2    <!-- CARDS-->
 3    <div class="col-sm-12 col-md-12 col-lg-12 row" style="margin:auto;">
 4        <!-- CARD1-->
 5        <div class="col-sm-12 col-md-4 col-lg-4" id="div_alert1"> <!-- Identificador de la card-->
 6            <div class="card border-info m-2">
 7                <div class="card-body" style="margin:auto;">
 8                    <center>
 9                        <h2 class="card-title">Total de Ajustes Entrantes</h2> <!-- Título -->
10                        <p class="card-text" style="font-size: 25px;" id="textAlert1">0</p> <!-- Texto (modificable) -->
11                        <i class="fas fa-building" style="font-size:30px;"></i> <!-- Ícono (opcional) -->
12                    </center>
13                </div>
14            </div>
15        </div>
16        <!-- CARD2-->
17        <div class="col-sm-12 col-md-4 col-lg-4" id="div_alert2"> <!-- Identificador de la card-->
18            <div class="card border-info m-2" >
19                <div class="card-body" style="margin:auto;">
20                    <center>
21                        <h2 class="card-title">Total de Ajustes Salientes</h2> <!-- Título -->
22                        <p class="card-text" style="font-size: 25px;" id="textAlert2">0</p> <!-- Texto (modificable) -->
23                        <i class="fas fa-check" style="font-size:30px;"></i> <!-- Ícono (opcional) -->
24                    </center>
25                </div>
26            </div>
27        </div>
28        <!-- CARD 3 (Indicador gauge)-->
29        <div class="col-sm-12 col-md-4 col-lg-4" id="div_alert3"> <!-- Identificador de la card-->
30            <div class="card border-info m-2" >
31                <div class="card card_border_none">
32                <div id='gaugeFirst' style="margin:auto;align-items: center;"></div> <!-- Identificador del gauge -->
33                <div style="text-align:center;">
34                    <span class="text-dark" id="text_gaugeFirst"></span> <!-- Texto (modificable) -->
35                </div>
36            </div>
37        </div>
38    </div>
39</div>
../../_images/Reportes39.png

Un gráfico proporciona una representación visual de datos o información. Su propósito es facilitar la comprensión y el análisis de datos mediante representaciones visuales, lo que permite identificar patrones, tendencias y relaciones de manera rápida y clara.

Para el desarrollo de un gráfico, se utiliza la biblioteca chartjs . Aunque existen muchos tipos de gráficos, en el siguiente ejemplo se presenta una gráfica de barras, la cual es la más utilizada en reportes.

Importante

Asegúrese de colocar el código dentro de la clase row y cambiar los ids necesarios.

El siguiente bloque de código presenta la definición del canvas y el contenedor donde se presentará la gráfica. Considere lo siguiente:

  • Aunque no es recomendable utilizar estilos en línea, incluya el atributo overflow-y: scroll (línea 3) para indicar que el elemento debe desplazarse verticalmente si excede el espacio disponible dentro del contenedor para que el diseño no se vea afectado.

  • Asegúrese de establecer un ancho y alto fijo al contenedor de la gráfica en base al contenedor padre (línea 5).

  • Asegúrese de aplicar un id claro al canvas para dibujar el gráfico. Este también puede llevar un orden en caso de tener más de una gráfica (línea 6).

Nota

Recuerde que la estructura y el relleno de la gráfica, así como cualquier otro elemento, se especifican en el archivo data.js .

 1<!-- Content -->
 2<div class="row" style="margin-top:20px;" id="divContent">
 3    <div class="col-sm-12 col-md-12 col-lg-12 div_class mt-2" style="align-items: center; overflow-y: scroll;"> <!-- Scroll -->
 4        <div id="firstElement"> <!-- Identificador del contenedor de la gráfica -->
 5            <div style="width: 1000px;height: 500px;margin: auto;">
 6                <canvas id="graphicFirst"></canvas> <!-- Identificador del gráfico -->
 7            </div>
 8        </div>
 9    </div>
10</div>
../../_images/Reportes40.png
Código content
Header#
 1<!-- Content -->
 2<div style="width:100%">
 3    <div class="app" id="appCont" style="padding-top: 0px;">
 4
 5        <!--Session -->
 6        <div class="row inicio_ses" id="inicio_ses">
 7            <div class="errorLogin" id="errorLog"></div>
 8            <div class="control">
 9                <div class="renglon">
10                    <h3>Usuario: </h3>
11                    <input class="form-control ds-input" id="user" name="user" value="">
12                </div>
13                <div class="renglon">
14                    <h3>Contraseña: </h3>
15                    <input class="form-control ds-input" type="password" id="pass" name="pass" value="">
16                </div>
17                <div class="controlBtn">
18                <div class="btn btn-primary" onclick="login()">Login</div>
19                <div class="btn btn-primary" onclick="reset()">Reset</div>
20                </div>
21            </div>
22        </div>
23
24        <!--Title Demo -->
25        <div id="title_demo" style="margin-bottom: 20px;">
26            <center>
27                <h1><span>Demo data</span>&nbsp;&nbsp;</h1>
28            </center>
29        </div>
30
31        <!--Options FIlter -->
32        <div class="col-sm-12 col-md-12 col-lg-12 row" id="divOptions">
33            <button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#firstParameters" aria-expanded="false" aria-controls="collapseExample" id="buttonFilter">
34                <i class="fa-solid fa-filter"></i>
35            </button >  &nbsp;  &nbsp;
36            <div class="btn btn-primary" onclick="runFirstElement()" >Run</div>
37        </div>
38
39        <!--Filters -->
40        <div id="firstParameters" class="collapse row show">
41            <div class="col-sm-12 col-md-3 col-lg-3">
42                <h5>Fecha Desde: </h5>
43                <input class="form-control ds-input" type="date" id="date_from" name="date_from">
44            </div>
45            <div class="col-sm-12 col-md-3 col-lg-3">
46                <h5>Fecha Hasta: </h5>
47                <input class="form-control ds-input" type="date" id="date_to" name="date_to">
48            </div>
49
50            <div class="col-sm-12 col-md-3 col-lg-3" >
51                <h5>Promotor: </h5>
52                <select class="form-control mdb-select md-form" id="promotor">
53                    <option value="">--Seleccione--</option>
54                </select>
55            </div>
56        </div>
57
58        <!--Content -->
59        <div class="row" style="margin-top:20px;"  id="divContent">
60            <!--Primer Elemento -->
61            <div class="col-sm-12 col-md-12 col-lg-12" style="align-items: center;overflow-y: scroll;">
62                <section class="title_tables">
63                    <h3><span>Recepción Visitas</span>&nbsp;&nbsp;
64                        <button class="btn btn-primary" id="download_csv_firstElement"><i class="fa-solid fa-file-csv"></i></button>
65                        <button class="btn btn-success" id="download_xlsx_firstElement"><i class="fa-regular fa-file-excel"></i></button>
66                    </h3>
67                    <hr class="hrFirstElement">
68                </section>
69                <div id="firstElement" ></div>
70            </div>
71        </div>
72    </div>
73</div>

Librerías#

Este bloque se localiza en la sección final de la etiqueta body, donde se especifican las rutas de los archivos JavaScript para las bibliotecas utilizadas en las funcionalidades del reporte. Entre estas bibliotecas se incluyen Tabulator, Chart.js, jQuery, Bootstrap, Select2, Plotly, así como los Utils de Linkaform y Servido. Además, se especifica la ubicación de los archivos JavaScript encargados de procesar y mostrar la información.

Nota

Los Utils son funciones propias de Linkaform, que se emplean para ciertas tareas como descargas de gráficos, imágenes, enviar peticiones al backend, entre otras.

Para acceder a las bibliotecas, se utiliza tanto la opción del CDN como la URL correspondiente. Dado que Servido se encuentra alojado en un contenedor Docker, se opta por referenciar las versiones alojadas en los servidores del CDN en lugar de descargar los recursos directamente desde el servidor local. Esta elección se debe a que realizar builds cada vez que se actualizan las bibliotecas y ejecutar las versiones minificadas resultaría más pesado en comparación con mantener enlaces directos a las versiones actuales de las bibliotecas.

Advertencia

Una desventaja al hacer referencia a bibliotecas almacenadas en CDNs es la posibilidad de que dichas bibliotecas experimenten fallas debido a interrupciones en el servicio del CDN provocando acciones inesperadas en los reportes.

Regularmente, los links no cambian, a excepción de la llamada de sus archivos JS ubicados al final del documento.

 1<!-- TABULATOR -->
 2<script type="text/javascript" src="https://oss.sheetjs.com/sheetjs/xlsx.full.min.js"></script>
 3
 4<!-- tabulator : PDF Downlowd-->
 5<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
 6<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.20/jspdf.plugin.autotable.min.js"></script>
 7<link href="https://unpkg.com/tabulator-tables/dist/css/tabulator.min.css" rel="stylesheet">
 8<script type="text/javascript" src="https://unpkg.com/tabulator-tables/dist/js/tabulator.min.js"></script>
 9
10<!-- chartjs -->
11<script type="text/javascript" src=" https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
12<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
13<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.min.js" integrity="sha512-R/QOHLpV1Ggq22vfDAWYOaMd5RopHrJNMxi8/lJu8Oihwi4Ho4BRFeiMiCefn9rasajKjnx9/fTQ/xkWnkDACg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
14<script type="text/javascript" src="https://unpkg.com/chart.js-plugin-labels-dv/dist/chartjs-plugin-labels.min.js"></script>
15
16<!-- Jquery -->
17<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
18
19<!-- Bootstrap -->
20<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
21<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
22<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
23
24<!-- Jquery Gauge -->
25<script src='https://cdn.plot.ly/plotly-2.14.0.min.js'></script>

A excepción de utils, aquí se encuentran algunas librerías minificadas, como chroma, que permite crear paletas de colores automáticamente, útil cuando se necesitan ciertos colores para gráficos. Además, la librería sweetalert2 permite crear alertas atractivas y personalizadas.

1<script type="text/javascript" src="../styles/js/chroma.min.js"></script>
2<script type="text/javascript" src="../styles/js/sweetalert2.all.min.js"></script>

También se encuentran archivos propios de Servido, correspondientes a las funciones API.

1<script type="text/javascript" src="../utils/lkf_utils.js"></script>
2<script type="text/javascript" src="../utils/servido_utils.js"></script>

El bloque de código anterior importa el archivo servido_utils.js, que se encarga de configurar el inicio de sesión, gestionar usuarios, contraseñas y configurar las cookies con información sensible como sessionId, userId, userJwt, userName y userParentId. Además, proporciona funciones útiles como getPalleteColors, setSpinner, getChartDownload, getDownload, setDateFilterMonth.

En el último bloque, se llaman a los archivos encargados de gestionar el reporte y el archivo con la data ficticia que se verá reflejada en las gráficas, tablas, u algún otro elemento que haya asignado.

1<script type="text/javascript" src="./reporte_visitas.js"></script>
2<script type="text/javascript" src="./reporte_visitas_data.js"></script>

En la siguiente pestaña desplegable, encontrará el código de un archivo HTML.

Nota

Por favor, considere leer los comentarios dentro del código para comprender los elementos.

Código completo archivo HTML
  1<!DOCTYPE html>
  2<html lang="en" dir="ltr">
  3<head>
  4    <!-- Metadatos y configuraciones iniciales -->
  5    <meta charset="utf-8">
  6    <title>Servido</title>
  7    <meta name="title" content="Servido">
  8    <meta name="description" content="Reporte Visitas">
  9    <!-- Icono de la página -->
 10    <link type="image/x-icon" rel="shortcut icon" href="../styles/img/favicon.ico">
 11    <!-- Configuración de la vista en dispositivos -->
 12    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
 13
 14    <!-- Enlaces a bibliotecas externas (CDN) -->
 15    <link type="image/x-icon" rel="shortcut icon" href="../styles/img/favicon.ico">
 16    <!--Bootstrap -->
 17    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
 18    <!--Font Awesome -->
 19    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
 20    <!-- Utils -->
 21    <link rel="stylesheet" href="../styles/css/sweetalert2.min.css">
 22    <link rel="stylesheet" href="../styles/css/styles.css">
 23    <link rel="stylesheet" href="style.css">
 24</head>
 25<body>
 26    <!-- Header (Barra de navegación) -->
 27    <nav class="navbar header">
 28        <div class="navbar-brand">
 29            <div class="row">
 30                <!-- Logo -->
 31                <div class="col-md-6">
 32                    <a href="index.html">
 33                        <div class="logo_marca">
 34                            <img src="https://app.linkaform.com/img/login-linkaform-logo.png" alt="LinkaForm" id="image_log">
 35                        </div>
 36                    </a>
 37                </div>
 38                <!-- Opción para cerrar sesión -->
 39                <div class="col-md-6">
 40                    <div class="container">
 41                        <div class="back"  id="atras"><i class="fa fa-solid fa-arrow-left"></i>Atrás</div>
 42                        <div class="close" id="close_sesion"><a onclick="closeSession();"><i class="fa-solid fa-lock"></i>Cerrar Sesión</a></div>
 43                    </div>
 44                </div>
 45            </div>
 46            <!-- Nombre del reporte (cambiar) -->
 47            <div class="col-md-12">
 48                <h1 id="title_report">Reporte Visitas</h1>
 49            </div>
 50        </div>
 51    </nav>
 52
 53    <!-- Estilo de carga (Loading) -->
 54    <div class="loading-container">
 55        <div class="spinner-border text-primary" role="status">
 56            <span class="sr-only">Loading...</span>
 57        </div>
 58    </div>
 59
 60    <!-- Contenido principal -->
 61    <div style="width:100%">
 62        <div class="app" id="appCont" style="padding-top: 0px;">
 63            <!-- Inicio de sesión -->
 64            <div class="row inicio_ses" id="inicio_ses">
 65                <!-- Formulario de inicio de sesión -->
 66                <div class="errorLogin" id="errorLog"></div>
 67                <div class="control">
 68                    <div class="renglon">
 69                        <h3>Usuario: </h3>
 70                        <input class="form-control ds-input" id="user" name="user" value="">
 71                    </div>
 72                    <div class="renglon">
 73                        <h3>Contraseña: </h3>
 74                        <input class="form-control ds-input" type="password" id="pass" name="pass" value="">
 75                    </div>
 76                    <!-- Botones -->
 77                    <div class="controlBtn">
 78                        <div class="btn btn-primary" onclick="login()">Login</div>
 79                        <div class="btn btn-primary" onclick="reset()">Reset</div>
 80                    </div>
 81                </div>
 82            </div>
 83
 84            <!-- Título de demo -->
 85            <div id="title_demo" style="margin-bottom: 20px;">
 86                <center>
 87                    <h1><span>Demo data</span>&nbsp;&nbsp;</h1>
 88                </center>
 89            </div>
 90
 91            <!-- Opciones de filtro -->
 92            <div class="col-sm-12 col-md-12 col-lg-12 row" id="divOptions">
 93                <button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#firstParameters" aria-expanded="false" aria-controls="collapseExample" id="buttonFilter">
 94                    <i class="fa-solid fa-filter"></i>
 95                </button >  &nbsp;  &nbsp;
 96                <div class="btn btn-primary" onclick="runFirstElement()" >Run</div>
 97            </div>
 98
 99            <!-- Filtros -->
100            <div id="firstParameters" class="collapse row show">
101                <div class="col-sm-12 col-md-3 col-lg-3">
102                    <h5>Fecha Desde: </h5>
103                    <input class="form-control ds-input" type="date" id="date_from" name="date_from">
104                </div>
105                <div class="col-sm-12 col-md-3 col-lg-3">
106                    <h5>Fecha Hasta: </h5>
107                    <input class="form-control ds-input" type="date" id="date_to" name="date_to">
108                </div>
109
110                <div class="col-sm-12 col-md-3 col-lg-3" >
111                    <h5>Promotor: </h5>
112                    <select class="form-control mdb-select md-form" id="promotor">
113                        <option value="">--Seleccione--</option>
114                    </select>
115                </div>
116            </div>
117
118            <!-- Elementos del contenido (Tablas, gráficas, etc.) -->
119            <div class="row" style="margin-top:20px;"  id="divContent">
120                <!--Primer Elemento -->
121                <div class="col-sm-12 col-md-12 col-lg-12" style="align-items: center;overflow-y: scroll;">
122                    <section class="title_tables">
123                        <h3><span>Recepción Visitas</span>&nbsp;&nbsp;
124                            <button class="btn btn-primary" id="download_csv_firstElement"><i class="fa-solid fa-file-csv"></i></button>
125                            <button class="btn btn-success" id="download_xlsx_firstElement"><i class="fa-regular fa-file-excel"></i></button>
126                        </h3>
127                        <hr class="hrFirstElement">
128                    </section>
129                    <div id="firstElement" ></div>
130                </div>
131            </div>
132        </div>
133    </div>
134</body>
135
136<!-- Bibliotecas JavaScript -->
137
138<!-- TABULATOR -->
139<script type="text/javascript" src="https://oss.sheetjs.com/sheetjs/xlsx.full.min.js"></script>
140
141<!-- PDF Download para Tabulator -->
142<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
143<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.20/jspdf.plugin.autotable.min.js"></script>
144<link href="https://unpkg.com/tabulator-tables/dist/css/tabulator.min.css" rel="stylesheet">
145<script type="text/javascript" src="https://unpkg.com/tabulator-tables/dist/js/tabulator.min.js"></script>
146
147<!-- chartjs -->
148<script type="text/javascript" src=" https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
149<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
150<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.0.0/chartjs-plugin-datalabels.min.js" integrity="sha512-R/QOHLpV1Ggq22vfDAWYOaMd5RopHrJNMxi8/lJu8Oihwi4Ho4BRFeiMiCefn9rasajKjnx9/fTQ/xkWnkDACg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
151<script type="text/javascript" src="https://unpkg.com/chart.js-plugin-labels-dv/dist/chartjs-plugin-labels.min.js"></script>
152
153<!-- Jquery -->
154<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
155
156<!-- Bootstrap -->
157<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
158<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
159<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
160
161<!-- Bibliotecas y utilidades personalizadas -->
162<script type="text/javascript" src="../styles/js/chroma.min.js"></script>
163<script type="text/javascript" src="../styles/js/sweetalert2.all.min.js"></script>
164
165<script type="text/javascript" src="../utils/lkf_utils.js"></script>
166<script type="text/javascript" src="../utils/servido_utils.js"></script>
167
168<!-- Template -->
169<script type="text/javascript" src="./reporte_visitas.js"></script>
170<script type="text/javascript" src="./reporte_visitas_data.js"></script>
171</html>

Estructura js#

El archivo js en Servido contiene la lógica encargada de gestionar las solicitudes a la API de Linkaform, así como de procesar y presentar la información correspondiente en la estructura establecida.

Observe el siguiente bloque de código, el cual representa de manera general las variables y funciones principales que componen al archivo js.

Atención

Tenga en cuenta que el siguiente código está basado en un ejemplo para un reporte específico con una tabla. Sin embargo, consulte las tabs para identificar el funcionamiento para elementos como cards o gráficos.

En el contenido posterior podrá encontrar detalles sobre las funciones más relevantes, resaltando los elementos que puede personalizar. Por favor, compare los ids y clases usadas con el archivo HTML para comprender el funcionamiento.

Nota

Regularmente, las variables y funciones que no tienen ningún comentario como título contienen código genérico que rara vez se modifica; por lo tanto, se mantienen sin cambios.

 1let us = null;
 2let usTy = null;
 3let jw = null;
 4let userId = null;
 5let userJwt = null;
 6let userName = null;
 7let userParentId = null;
 8let scriptId = null;
 9
10$('#divOptions').hide();
11$('#title_report').hide();
12$('.title_tables').hide();
13hideElement("title_demo");
14hideElement("firstParameters");
15hideElement("firstElement");
16hideElement("secondElement");
17hideElement("thirdElement");
18
19window.onload = function(){ ...
20}
21
22function unHideReportElements(){ ...
23}
24
25const loading = document.querySelector('.loading-container');
26loading.style.display = 'none';
27
28//-----DEMO
29function loadDemoData(){ ...
30}
31
32//-----DATE
33function setDate(){ ...
34}
35
36//-----EXCUTION
37function runFirstElement(){ ...
38}
39
40function getFirstElement(dateTo, dateFrom, promotor){ ...
41}
42
43//-----TABLES
44function getDrawTable(id, columnsData, tableData, height = 500){ ...
45}
46
47//-----CATALOG
48function get_catalog(){ ...
49};

Variables globales y métodos#

Las variables globales siguientes se utilizan para retener información asociada a la cuenta que accede al reporte o al script y forman parte de las cookies. Estas variables se utilizan en el archivo servido_utils.

Advertencia

Las variables no se modifican.

1let us = null;
2let usTy = null;
3let jw = null;
4let userId = null;
5let userJwt = null; //Token del usuario
6let userName = null;
7let userParentId = null; //Id de la cuenta padre
8let scriptId = null; //Script del reporte

El siguiente bloque de código corresponde a métodos de jQuery, se utiliza para manipular el DOM de la página. Específicamente, oculta varios elementos visuales antes de cualquier interacción con el reporte. Lo hace tanto por su identificador único (id) como por su clase.

Independientemente del número de elementos en su reporte, incluya los elementos que debe ocultar. O en su defecto, si no tiene elementos agrupados, oculte según lo requiera. Por favor, revise los comentarios dentro del código.

 1$('#divOptions').hide(); // Oculta el elemento con ID "divOptions" (botón Run)
 2$('#title_report').hide(); // Oculta el elemento con ID "title_report" (título del reporte)
 3$('.title_tables').hide(); // Oculta el elemento con ID "title_tables" (Título de las tablas)
 4
 5// Oculta el elementos con la identificación proporcionada para que no se muestre en la pantalla.
 6hideElement("title_demo"); // Oculta el elemento con ID "title_demo" (titulo que especifica que el reporte contiene datos demo)
 7hideElement("firstParameters"); // Oculta el elemento con ID "firstParameters" (botón de filtros)
 8hideElement("firstElement"); // Oculta el primer elemento del reporte
 9
10// Ajuste el numero de elementos de su reporte
11hideElement("secondElement"); // Oculta el segundo elemento del reporte
12hideElement("thirdElement"); // Oculta el tercer elemento del reporte
13hideElement("fourthElement"); // Oculta el cuarto elemento del reporte
14hideElement("thirdElement"); // Oculta el quinto elemento del reporte
15hideElement("fiveElement"); // Oculta el sexto elemento del reporte
16
17// Oculta elemento por elemento
18hideElement("div_alert1"); // Card1
19hideElement("div_alert2"); // Card2 línea 5) para traer la data única de un catálogo. Por favor, lea detenidamente los comentarios.
20hideElement("div_alert3"); // Card3

Función window.onload#

La función window.onload() se activa siempre que la pantalla se carga por completo. Además, procesa los parámetros de la URL para actualizar los elementos del reporte en función a esos parámetros. También se encarga de manipular el contenido de los filtros mediante el ID de los elementos.

En las líneas 6-8, verifica si la clave (key) recibida es igual a script_id, es decir, lo que se recibe como parámetro de la URL.

Ver también

Consulte la sección URLs de acceso, específicamente en la de Servido .

Revise la configuración del reporte en la sección Crear reporte .

De manera similar, en las líneas 10-13, verifica si se está accediendo al entorno de pruebas para apuntar y acceder a los valores de preproducción.

Ver también

Consulte: Entorno de prueba (Test Environment) .

 1window.onload = function(){ // Esta función se ejecutará cuando la ventana haya cargado completamente.
 2var qs = urlParamstoJson(); // Obtiene los parámetros de la URL y los convierte en un objeto.
 3var formNode = document.getElementById("appCont"); // Obtiene el elemento del DOM del contenido de "inicio de sesión".
 4    for(var key in qs){ // Recorre los parámetros de la URL.
 5    // Verifica si el parámetro es "script_id" y lo convierte en un entero.
 6    if (key === 'script_id' ){
 7    scriptId = parseInt(qs[key]);
 8    }
 9     // Verifica si el parámetro es "env" y establece la URL en función del valor.
10    if (key === 'env') {
11    if (qs[key] === 'test'){
12        url = "https://preprod.linkaform.com/api/"; // Establece la URL de la API en modo de prueba.
13    }
14    }
15    // Verifica si el parámetro es "title" y establece el texto del elemento con el ID "title_report" que es el título del reporte.
16    if (key ==='title'){
17    $("#title_report").text(qs[key]);
18    }
19        var elements = getAllElementsWithAttribute(formNode, 'data-infosync-id', key); // Obtiene todos los elementos con el atributo 'data-infosync-id' igual a 'key'.
20        var value = decodeURI(qs[key]); // Decodifica el valor del parámetro.
21     // Si el parámetro es 'infosyncRecordID', establece su valor en un elemento con el mismo ID.
22    if (key === 'infosyncRecordID'){
23    var recId = document.getElementById("infosyncRecordID");
24    recId.value = value;
25    }
26        else if(elements.length > 0){
27            // Si existen elementos con el atributo 'data-infosync-id', actualiza sus valores según el tipo de elemento del filtro.
28            switch(elements[0].type){
29                case 'text':
30                    elements[0].value = value;
31                    break;
32                case 'textarea':
33                    elements[0].value = value;
34                    break;
35                case 'select-one':
36                    elements[0].value = value;
37                    break;
38                case 'radio':
39                    for(var idx in elements){
40                        if(elements[idx].value === value){
41                            elements[idx].checked = true;
42                        }
43                    }
44                    break;
45                case 'checkbox':
46                    var values = value.split(';');
47                    for(var idx in elements){
48                        if(values.indexOf(elements[idx].value) !== -1){
49                            elements[idx].checked = true;
50                        }
51                    }
52                    break;
53            }
54        }
55    }

Continuando con la función window.onload de forma general, la condicional (línea 11) verifica si se ha iniciado sesión. El parámetro us corresponde al ID del usuario (línea 2), el parámetro jw al token del usuario (línea 3).

Si el parámetro scriptId es nulo, el entorno se configurará como demo. Si la condición se cumple, se ejecutan otras acciones. Revise los comentarios dentro del código para comprender el flujo.

 1// Obtiene valores de cookies y almacena en variables.
 2us = getCookie("userId");
 3jw = getCookie("userJwt");
 4userParentId = getCookie("userParentId");
 5
 6// Oculta elementos con los IDs "close_sesion" y "firstParameters".
 7hideElement("close_sesion"); // opción para cerrar sesión.
 8hideElement("firstParameters");// opción para mostrar filtros.
 9
10// Verifica si las cookies "userId" y "userJwt" no están vacías o si "scriptId" es nulo.
11if(us != "" && jw != "" || scriptId===null){
12    hideElement("inicio_ses"); // Oculta el inicio de sesión porque ya hay una sesión activa.
13    unhideElement("close_sesion"); // Muestra el botón "cerrar sesión" que aparece en la parte superior derecha.
14    getCompanyLogo(userParentId); // Obtiene el logo de la empresa según el "userParentId".
15
16    // Asigna valores a variables globales.
17    userId = us;
18    userJwt = jw;
19    userName = getCookie("userName"); //Obtiene el nombre del usuario a través de la cookie.
20    document.getElementById("firstParameters").style.removeProperty('display');  // Restablece la propiedad "display" del elemento con los filtros del reporte "id firstParameters" (lo muestra).
21    unHideReportElements() // Muestra elementos del reporte (llama a una función "unHideReportElements" ubicada en código posterior).
22
23    // Si "scriptId" es nulo, carga datos de la demo y ejecuta la función correspondiente de loadDemoData.
24    if (scriptId == null) {
25    loadDemoData(); // Ejecuta la función "loadDemoData()". Podrá encontrar la explicación en contenido posterior.
26    }
27    //--Styles
28    setSpinner(); // Carga la animación de spinner cuando se carga la data.
29    setDate(); // Ejecuta la función "setDate()". Podrá encontrar la explicación en contenido posterior.
30    get_catalog(); // Ejecuta la función "get_catalog()". Podrá encontrar la explicación en contenido posterior.
31    $('#divOptions').show(); // Muestra las opciones de filtro.
32    $('#title_report').show(); // Muestra el título del reporte.
33    document.getElementById("firstParameters").style.removeProperty('display');
34
35} else {
36    // Si las condiciones anteriores no se cumplen, muestra el elemento con el ID "inicio_ses" que es el formulario para la autenticación.
37    unhideElement("inicio_ses");
38
39    // Oculta varios elementos, incluyendo "divContent", "divOptions", "title_report" y elementos con la clase "title_tables".
40    $('#divContent').hide(); // Elementos que se utilizan para representar la data de las formas (Tablas, gráficos, etc.).
41    $('#divOptions').hide(); // Botones opciones de filtro.
42    $('#title_report').hide(); // Título del reporte.
43    $('.title_tables').hide(); // Títulos de las tablas (NOTA: Este elemento corresponde a una tabla, en caso de algún otro elemento deberá colocarlo aquí).
44    hideElement("firstElement-Buttons");
45}
46///-----HIDE AND SHOW
47for(var key in qs){ // Recorre los parámetros de la URL.
48    // Si el parámetro es "embed" y tiene un valor, oculta los elementos con los IDs "close_sesion" (opción para cerrar sesión, ubicada en la parte superior derecha) y "image_log".
49    if (key === 'embed'){
50    if (qs[key]){
51        $("#close_sesion").hide();
52        $("#image_log").hide();
53    }
54    }
55}
56}

Función unHideReportElements#

La siguiente función unHideReportElements() se encarga de mostrar los elementos específicos en la página que son necesarios para el reporte al iniciar sesión. Lea los comentarios.

Atención

Configure aquí todos los elementos del reporte que deben mostrarse al iniciar sesión.

 1function unHideReportElements(){
 2
 3unhideElement("firstElement-Buttons"); // Botones opciones de filtro.
 4unhideElement("firstParameters"); // Filtros.
 5unhideElement("close_sesion"); // Opción para cerrar sesión.
 6}
 7
 8// La variable "loading" almacena el primer elemento con la clase "loading-container" (spinner).
 9const loading = document.querySelector('.loading-container');
10
11// Oculta visualmente el elemento seleccionado estableciendo su propiedad de estilo 'display' en 'none'.
12loading.style.display = 'none';

Función loadDemoData#

La función loadDemoData() está diseñada para cargar datos de demostración y otros elementos como tablas, tarjetas y gráficas en el reporte.

Atención

Esta es una de las funciones más importantes que debe adaptar. Revise las siguientes pestañas que ejemplifican escenarios con diferentes elementos. Considere los mismos ejemplos que en los elementos de representación , a medida que avance revise y compare ids y clases del código con la documentación.

En esta pestaña encontrará únicamente el código correspondiente a una tabla.

Observe que en la línea 11 se llama a la función getDrawTable , la cual se utiliza para obtener datos y elementos de una tabla, enviando los siguientes cuatro parámetros:

  • firstElement: Id de la tabla.

  • columsTable1: Variable que contiene un array de objetos que representan las columnas de la tabla (biblioteca de tablas Tabulator).

Ver también

Consulte el archivo data.js , donde está ubicada la variable mencionada anteriormente.

  • dataTable1: Variable que contiene un array de objetos que representan los datos de la tabla. Recuerde que, dado que es un reporte demo, se llena con información ficticia que no se extrae de la base de datos con registros reales.

Ver también

Consulte el archivo data.js , donde está ubicada la variable mencionada anteriormente.

  • 350: Es la altura máxima en píxeles que medirá la tabla.

 1//-----DEMO
 2// Verifica si el entorno es la demo, en caso de serlo muestra ciertos elementos pertenecientes al mismo.
 3function loadDemoData(){
 4unhideElement("title_demo")// Muestra el elemento con la clase "title_demo". En este caso, coloca "Demo data" debajo del titulo del reporte para indicar que es un reporte de demostración.
 5$('.title_tables').show();// Muestra todos los elementos con la clase "title_tables". En este caso, el titulo de la o las tablas (dependiendo de cuantas tablas haya establecido).
 6
 7// Restablece la propiedad "display" (elimina la propiedad display del estilo del elemento) para mostrar y permitir que el elemento con el ID "firstParameters" (opciones y botones de filtros) force a la regla de estilo predeterminada a abarcar todo el espacio de la página.
 8document.getElementById("firstParameters").style.removeProperty('display');
 9
10// Llama a la función "getDrawTable" para obtener y mostrar una tabla.
11getDrawTable('firstElement', columsTable1, dataTable1, 350);
12// Restablece la propiedad "display" (eliminar la propiedad display del estilo del elemento) para mostrar y permitir que el elemento con el ID "firstElement" (tabla) force a abarcar todo el espacio de la página.
13document.getElementById("firstElement").style.removeProperty('display');
14}

En esta pestaña encontrará el código necesario para presentar datos de demostración para tarjetas (cards). Aunque anteriormente se recalcó que estos datos pueden aplicarse directamente en el span correspondiente.

Observe la línea de código 16, donde se llama a la función getDrawGauge , que se utiliza para obtener datos y elementos de un indicador Gauge. Esta función envía dos parámetros:

  • gaugeFirst: Id de la tarjeta (indicador Gauge).

  • dataGauge1: Variable que contiene la data del medidor.

 1function loadDemoData(){
 2
 3unhideElement("title_demo"); // Muestra el titulo que especifica que es un reporte demo.
 4unhideElement("div_alert1"); // Muestra la tarjeta 1
 5unhideElement("div_alert2"); // Muestra la tarjeta 2
 6unhideElement("div_alert3"); // Muestra el indicador Gauge
 7
 8// Restablece la propiedad "display" (elimina la propiedad display del estilo del elemento) para mostrar y permitir que el elemento con el ID "firstParameters" (opciones y botones de filtros) force a la regla de estilo predeterminada a abarcar todo el espacio de la página.
 9document.getElementById("firstParameters").style.removeProperty('display');
10
11// Establecen su contenido de texto interno utilizando la propiedad innerText.
12document.getElementById("textAlert1").innerText = 50;
13document.getElementById("textAlert2").innerText = 10;
14
15// Llama a la función getDrawGauge()
16getDrawGauge('gaugeFirst', dataGauge1)
17document.getElementById("firstGauge").style.removeProperty('display');
18}

Función setDate#

La función setDate() está diseñada para establecer valores iniciales en los filtros de tipo fecha del reporte. Estos son los inputs con los IDs date_to y date_from que existen en la estructura de los filtros establecidos en el archivo HTML. Lea los comentarios del código.

 1//-----DATE
 2function setDate(){ // Función para establecer valores predeterminados en campos de fecha
 3// Array de representaciones de dos dígitos de los 12 meses del año
 4array_month = ['01','02','03','04','05','06','07','08','09','10','11','12'];
 5
 6//---DATE TO
 7// Obtiene fecha actual como fecha final del filtro hasta (date_to)
 8date_to = new Date();
 9year = date_to.getFullYear();
10month = array_month[date_to.getMonth()];
11day = date_to.getDate();
12date_to = year +'-'+ month +'-'+ day;
13$('#date_to').val(date_to); // Establece el valor en el campo de fecha final
14
15//---DATE FROM
16// Obtiene fecha actual menos 30 días como fecha de inicio (date_from)
17date_from = new Date();
18date_from.setDate(date_from.getDate() - 30)
19
20year = date_from.getFullYear();
21month = array_month[date_from.getMonth()];
22day = date_from.getDate();
23date_from = year +'-'+ month +'-'+ day;
24$('#date_from').val(date_from);// Establece el valor en el campo de fecha de inicio
25}

Función get_catalog#

La función get_catalog() se encarga de realizar una petición (puede ser a producción o a preproducción dependiendo del parámetro que contenga en la URL, línea 5) al servidor para traer la data única de un catálogo.

Prudencia

La siguiente función está diseñada para realizar una petición para el selector Promotor (filtro) correspondiente a un catálogo. Puede usarla como referencia en caso de que necesite extraer información para un filtro de un catalogo. Consulte la sección Catálogos para más detalles.

Cada usuario que inicia sesión en su cuenta tiene un token (Jwt) línea 13, el cual se envía en la petición del script. Si el usuario tiene acceso al script, ya sea porque se le compartió o pertenece al grupo de la cuenta padre, podrá ejecutarlo. En caso contrario, se le indicará a través de un mensaje que no tiene acceso y se le sugerirá iniciar sesión.

Ver también

Consulte Ver ID del script (línea 8).

Observe la condicional en el bloque de código entre las líneas 20-39. Aquí es donde se extrae la información del catálogo. Por favor, lea detenidamente los comentarios.

Ver también

Recuerde colocar el id correspondiente del campo de su forma. Consulte Opciones avanzadas para conocer el id del campo.

../../_images/Reportes41.png
 1//-----CATALOG
 2// Función para obtener datos de un catálogo a través de una solicitud fetch
 3function get_catalog(){
 4// Realiza una solicitud fetch usando el método POST
 5fetch(url + 'infosync/scripts/run/', {
 6    method: 'POST',
 7    body: JSON.stringify({ // Convierte a un JSON
 8        script_id: 95556, // Id del script al que debe apuntar
 9        option: 0, // Determina que consulta debe realizar, en este caso 0 le indica que debe realizar una consulta a un catalogo, en el caso de que fuera 1 seria una petición normal a la forma.
10    }),
11    headers:{
12        'Content-Type': 'application/json',
13        'Authorization': 'Bearer '+userJwt
14    },
15    })
16    // Procesa la respuesta en formato JSON
17    .then(res => res.json())
18    .then(res => {
19    // Verifica si la petición fue exitosa (success = true)
20    if (res.success) {
21        // Verifica si hay elementos en el catálogo devuelto
22        if (res.response.catalog.length){
23        array_value = []
24        // Itera sobre los elementos del catálogo para extraer valores únicos
25        for (i = 0; i < res.response.catalog.length; i++) {
26            if (!array_value.includes(res.response.catalog[i]['63dc0f1ec29b8336b7b72615'])) {
27            array_value.push(res.response.catalog[i]['63dc0f1ec29b8336b7b72615'])
28            }
29        }
30        // Ordena los valores únicos en el array
31        array_value.sort();
32        // Limpia y actualiza un elemento del DOM (select con ID "promotor" (filtro))
33        $("#promotor").empty();
34        $('#promotor').append('<option value="--">--Seleccione--</option>');
35        // Itera sobre los valores únicos y agregar opciones al elemento "promotor"
36        for (i = 0; i <array_value.length; i++) {
37            $('#promotor').append('<option value="'+ array_value[i] +'">'+array_value[i]+'</option>');
38        }
39    }
40}
../../_images/Reportes42.png

Función runFirstElement#

La función runFirstElement() se ejecuta cuando se presiona el botón Run de los filtros. Obtiene las referencias de los filtros para validar que no estén vacíos (línea 10) y poder traer la data correspondiente (línea 12). Por favor, continue leyendo los comentarios dentro del código.

Atención

Ajuste esta función de acuerdo a los filtros que necesite. En este caso, los campos (filtros) son de fechas y promotores. Si no están vacíos y están completos, llama a la función getFirstElement con los valores de fecha y promotor. Si los campos de fecha están vacíos, muestra una alerta visual utilizando la biblioteca Swal (SweetAlert2 ), solicitando al usuario que ingrese un rango de fechas antes de continuar.

../../_images/Reportes43.png
 1//-----EXCUTION
 2// Se encarga de gestionar los filtros existentes, toma los valores de "date_to" (de esta fecha) y "date_from" (a esta fecha) y las almacena en las variables.
 3function runFirstElement(){
 4// Obtiene referencias a los elementos HTML con los IDs "date_from", "date_to" y "promotor".
 5let date_from = document.getElementById("date_from");
 6let date_to = document.getElementById("date_to");
 7let promotor = document.getElementById("promotor");
 8
 9// Verifica si los campos de fecha no están vacíos.
10if (date_from.value != null && date_to.value != null && date_from.value != "" && date_to.value != ""){
11    // Si los campos no están vacíos, llama a la función getFirstElement con los valores de fecha y promotor
12    getFirstElement(date_to.value, date_from.value, promotor.value);
13}
14else
15{
16    // Muestra un mensaje de alerta si los campos de fecha están vacíos
17    Swal.fire({
18    title: 'Rango de Fechas Requerido',
19    });
20}
21}

Función getFirstElement#

En términos generales, la función getFirstElement() obtiene los parámetros de los filtros y presenta datos dinámicos del servidor en los elementos del reporte.

La función se encarga de recibir las validaciones de los filtros (:ref: funcion-runFirstElement ) para realiza una solicitud al servidor (puede ser a producción o a preproducción dependiendo del parámetro que contenga en la URL, línea 9) utilizando el método POST.

Ver también

El scriptId es lo que se recibe como parámetro en la URL, línea 12 (Regrese y consulte la Función window.onload , específicamente las líneas 6-8, y lea los comentarios).

Después de procesar la respuesta del servidor, muestra u oculta elementos en la interfaz según el resultado. Si la respuesta es exitosa, se actualiza el elemento (tabla) con los datos recibidos. En caso de error se muestra un mensaje utilizando la biblioteca Swal (SweetAlert2 ) líneas 46-60. Lea detenidamente los comentarios dentro del código para comprender el flujo.

Nota

Los errores más comunes que pueden presentarse al hacer la solicitud pueden incluir:

  • No tener acceso a la información.

  • La sesión caducó (el token ha expirado).

Observe la línea de código número 40, llama a la función getDrawTable . Desglosando los parámetros que envía:

  • firstElement: Es el ID del div donde se necesita colocar la tabla.

  • columsTable1: Variable que contiene un array de objetos que representan las columnas de la tabla (biblioteca de tablas Tabulator Download Data ).

Prudencia

columsTable1 es la única variable que funciona tanto en el reporte demo como en el reporte operativo final. Las columnas pueden ser dinámicas o estáticas, sin embargo, al utilizar funciones propias de JavaScript es difícil usar el dinamismo a menos de que todas las columnas lleven la misma estructura. Consulte el archivo data.js para más detalles.

  • res.response.firstElement.tabledata: Son las filas extraídas del valor, es decir, toda la data real.

  • 450: Es la altura máxima en píxeles que medirá la tabla.

 1// Función para obtener datos de los elementos a través de una solicitud fetch
 2function getFirstElement(dateTo, dateFrom, promotor){
 3//----Hide Css
 4$("#divContent").hide(); // Oculta todos los elementos (tablas, gráficos, etc.) para que, al aplicar un filtro, los elementos se recarguen y no permanezcan visibles hasta que se complete la carga del nuevo filtro.
 5$('.load-wrapp').show(); // Muestra la animación del spinner para cargar la data.
 6$('.title_tables').hide(); // Asegura que el título de la o las tablas esté oculto para que cada vez que se aplique un filtro, los elementos vuelvan a cargarse.
 7
 8// Realiza una solicitud fetch usando el método POST para obtener datos del servidor
 9fetch(url + 'infosync/scripts/run/', {
10    method: 'POST',
11    body: JSON.stringify({ // Convierte a un JSON
12    script_id: scriptId,
13    // Parámetros (filtros) que recibirá el script
14    date_to: dateTo,
15    date_from: dateFrom,
16    promotor: promotor,
17    option: 1, // Determina que consulta debe realizar, en este caso 1 le indica que debe realizar una consulta normal es decir, a la forma
18    }),
19    headers:{
20    'Content-Type': 'application/json',
21    'Authorization': 'Bearer '+userJwt
22    },
23})
24 // Procesa la respuesta en formato JSON
25.then(res => res.json())
26.then(res => {
27    // Verifica si la petición fue exitosa (success = true)
28    if (res.success) {
29    //----Hide and show
30    $('.load-wrapp').hide(); // Oculta la animación del spinner para cargar la data
31    $("#divContent").show(); // Muestra todos los elementos (tablas, gráficos, etc.)
32    $('.title_tables').show(); // Se habilitan títulos de la o las tablas que estaban ocultas
33
34    // Observe en la consola del navegador la data extraída, almacenada en un objeto
35    console.log(res.response)
36
37    // Verificar si hay datos en la respuesta
38    if (res.response.firstElement.tabledata) {
39        // Llama a la función "getDrawTable()" para actualizar la tabla con los datos recibidos. NOTA: Consulte la función para más detalles ubicada posteriormente.
40        getDrawTable('firstElement', columsTable1, res.response.firstElement.tabledata, 450);
41        // Restablecer la propiedad 'display' para mostrar el elemento 'firstElement'
42        document.getElementById("firstElement").style.removeProperty('display');
43    }
44    } else {
45    // En caso de error, oculta el indicador de carga y muestra un mensaje de error
46    hideLoading();
47    if(res.code == 11){
48        Swal.fire({
49        title: 'Error',
50        html: res.error
51        });
52        $('.load-wrapp').hide();
53    } else {
54        Swal.fire({
55        title: 'Error',
56        html: res.error
57        });
58        $('.load-wrapp').hide();
59    }
60    }
61})
62}

Función getDrawTable#

La función getDrawTable() se utiliza para dibujar y configurar la tabla interactiva utilizando la biblioteca Tabulator . Proporciona opciones para descargar los datos de la tabla en formatos XLSX y CSV. A continuación, se describe el flujo de la función de manera general:

Prudencia

Esta función NO está estandarizada, pero si está preparada para funcionar con n cantidad de tablas que se requieran de un mismo reporte.

Observe la línea 4, donde el ID es el indicador de HTML que toma el valor de la variable id y lo concatena con el símbolo de almohadilla (#), creando así un selector de identificador completo para seleccionar un elemento específico en el documento HTML basado en su identificador (tabla).

Ejemplo

Si id tiene el valor firstElement, entonces # + id se convierte en #firstElement y eso se utilizará para seleccionar el elemento con el ID firstElement en el HTML. Es decir, no tendrá que repetir la función por cada tabla y colocar firstElement, secondElement y así sucesivamente.

Identifique las líneas de código de la 4-15, aquí se crea una instancia de Tabulator Download Data y se configuran aspectos de la tabla, como la altura, el diseño, los datos, la capacidad de redimensionar filas, la estructura de árbol de datos, la capacidad de copiar al portapapeles, la dirección del texto y las columnas.

Ver también

Para funciones más personalizadas considere revisar las opciones de tablas y ajuste las propiedades según sus necesidades. Revise la documentación correspondiente a la tabla.

En los bloques de código (18-27, 29-38) verifica si existe un elemento del DOM para la descarga de datos en formato XLSX y CSV (botones para descarga). Si existe, se reemplaza con una copia para evitar duplicados y se agrega un evento de clic para activar la descarga de datos en formato XLSX y CSV cuando se haga clic en el elemento.

 1//-----TABLES
 2function getDrawTable(id, columnsData, tableData, height = 500){
 3// Crear una instancia de Tabulator y configurar la tabla
 4var  table = new Tabulator("#" + id, {
 5    height:height +"px",
 6    layout:"fitDataTable",
 7    data:tableData,
 8    resizableRows:false,
 9    dataTree:true,
10    dataTreeStartExpanded:false,
11    clipboard:true,
12    clipboardPasteAction:"replace",
13    textDirection:"ltr",
14    columns:columnsData,
15});
16
17// Configuración para descargar datos en formato XLSX (Excel)
18if (document.getElementById("download_xlsx_"+id)){
19    // trigger download of data.xlsx file
20    // Reemplaza el elemento actual con una copia clonada del mismo elemento
21    document.getElementById("download_xlsx_"+id).replaceWith(document.getElementById("download_xlsx_"+id).cloneNode(true));
22    // Agrega un evento al elemento clonado para la descarga del archivo XLSX
23    document.getElementById("download_xlsx_"+id).addEventListener("click", function (){
24    // Utiliza la función "table.download" para descargar el contenido de la tabla en formato XLSX con el nombre de archivo "data.xlsx"
25    table.download("xlsx", "data.xlsx", {sheetName:"data"});
26    });
27}
28// Configuración para descargar datos en formato CSV
29if (document.getElementById("download_csv_"+id)){
30    //trigger download of data.csv file
31    // Reemplaza el elemento actual con una copia clonada del mismo elemento
32    document.getElementById("download_csv_"+id).replaceWith(document.getElementById("download_csv_"+id).cloneNode(true));
33    // Agrega un evento al elemento clonado para la descarga del archivo CSV
34    document.getElementById("download_csv_"+id).addEventListener("click", function (){
35    // Utiliza la función "table.download" para descargar el contenido de la tabla en formato CSV con el nombre de archivo "data.csv"
36    table.download("csv", "data.csv");
37    });
38}
39}

Función getDrawGauge#

La función getDrawGauge() utiliza la biblioteca plotly para dibujar y configurar un gráfico de tipo Gauge (medidor).

La función recibe dos parámetros:

  • id: El id del contenedor donde se dibujará el gráfico de Gauge.

  • data: Los datos necesarios para dibujar el gráfico de Gauge.

En la línea 3 se define un objeto layout que especifica las propiedades del diseño del gráfico. En este caso, se establecen el ancho, el alto y los márgenes del gráfico.

Nota

En el objeto layout, las propiedades t y b en el atributo margin especifican el margen superior (t de top) y el margen inferior (b de bottom).

Luego, se utiliza Plotly.newPlot() para crear un nuevo gráfico de Gauge. Se pasa el id, data y layout definido anteriormente como argumentos.

 1//-----GAUGE
 2function getDrawGauge(id, data){
 3var layout = {
 4width: 340,
 5height: 190,
 6margin: {
 7    t: 42 ,
 8    b: 0
 9    }
10};
11
12Plotly.newPlot(id, data, layout);
13}

Estructura data.js#

La estructura de un archivo data.js en Servido tiene el propósito de albergar configuraciones de las librerías utilizadas en el reporte. Es utilizado para proporcionar datos de relleno de tablas, gráficos y otros elementos y visualizar cómo se verá el reporte cuando se complete con datos reales. A continuación, se detalla más acerca de la estructura de un archivo data.js. Al final, encontrará el código completo:

El siguiente bloque de código contiene un array de objetos que representan las columnas de la tabla, continue:

  • Ubique la líneas de código 2-4, es una funcion propia de JavaScript diseñada para generar dinámicamente una URL para un enlace en función del valor del campo record_id en la fila actual de la tabla. Cada celda en la columna Folio tendrá un enlace único que apunta a la página de detalles del registro (Consulte: Visualizar registro ) correspondiente en la aplicación de Linkaform. Es decir, la función url se utiliza como parte del formateador para la columna Folio en Tabulator.

Método/Instrucción

Descripción

cell.getData()

Se utiliza para obtener los datos asociados con esa celda en la fila actual de la tabla. Asumiendo que la celda está asociada al conjunto de datos que incluye un campo llamado record_id.

record_id

Después de obtener los datos de la celda con getData(), se accede al valor específico del campo record_id y se extrae su valor.

formatter

Formateador de la celda por columna.

formateadorParams

Parámetros adicionales con el formateador, que debe contener un objeto con información adicional para configurar el formateador.

Ver también

Consulte formateador de tabla con url para más detalles o revise otras opciones para formatear tablas .

 1var columsTable1 = [
 2{title:"Folio", field:'folio', hozAlign:"right", formatter:"link", formatterParams:{
 3url:function(cell){return "https://app.linkaform.com/#/records/detail/" + cell.getData().record_id},
 4target:"_blank",}, headerFilter:"input",width:100},
 5{ title:"Store ID", field:'store_id',hozAlign:"right",width:200},
 6{ title:"Merchant", field:'merchant',hozAlign:"left",width:300},
 7{ title:"Store", field:'store',hozAlign:"left",width:300},
 8{ title:"Promotor", field:'promotor',hozAlign:"left",width:300},
 9{ title:"City", field:'city',hozAlign:"left",width:250},
10{ title:"State", field:'state',hozAlign:"left",width:250},
11{ title:"Fecha Inicio de Captura", field:'fecha_captura',hozAlign:"right",width:250},
12{ title:"Coordenadas Latitud", field:'cordenada_latitud',hozAlign:"right",formatter: "money",
13"formatterParams": {"symbol": "", "symbolAfter": "", "thousand": "",  precision:false},width:250},
14{ title:"Coordenadas Longitud", field:'cordenada_longitud',hozAlign:"right",formatter: "money",
15"formatterParams": {"symbol": "", "symbolAfter": "", "thousand": "",  precision:1},width:250},
16{ title:"Check In", field:'checkin',hozAlign:"right",width:250},
17{ title:"Check Out", field:'checkout',hozAlign:"right",width:250},
18{ title:"Tiempo Visita", field:'tiempo_visita',hozAlign:"right",width:250},
19];
../../_images/Reportes16.png
  • title: Texto de la columna.

  • field: Atributo key que permitirá enlzar las columnas con las filas.

  • hozAlign: Alineación de la data, puede ser righth, center o left, pero no justify.

  • width: Ancho de la columna en px.

Prudencia

Las columnas pueden ser dinámicas solamente si no se utilizan formateos específicos para la tabla. Es decir, si todas las columnas de la tabla son estáticas y usan la misma estructura (title, field, hozAlign y width), como se muestra en la línea 6.

El siguiente bloque de código representa un array de objetos de la data de la tabla.

Nota

Cada objeto dentro del arreglo representa una fila de datos con propiedades específicas.

 1var dataTable1 = [
 2{
 3    "folio": "850-11702",
 4    "record_id": "63eaed385a3ef7414d4899da",
 5    "store_id": "1209250816961081402",
 6    "merchant": "Calvin Klein Instore",
 7    "store": "Ck Parque Lindavista",
 8    "centro_comercial": "Parque Lindavista",
 9    "promotor": "Alberto Torres",
10    "city": "Gustavo A. Madero",
11    "fecha_creacion": "2023-02-14 08:08:56",
12    "checkin": "2023-02-14 08:03:49",
13    "checkout": "2023-02-14 08:08:45",
14    "tz_offset": -360.0,
15    "tiempo_visita": 296.0
16},
17{
18    "folio": "850-11702",
19    "record_id": "63eaed385a3ef7414d4899da",
20    "store_id": "1209250816961081402",
21    "merchant": "Calvin Klein Instore",
22    "store": "Ck Parque Lindavista",
23    "centro_comercial": "Parque Lindavista",
24    "promotor": "Alberto Torres",
25    "city": "Gustavo A. Madero",
26    "fecha_creacion": "2023-02-14 08:08:56",
27    "checkin": "2023-02-14 08:03:49",
28    "checkout": "2023-02-14 08:08:45",
29    "tz_offset": -360.0,
30    "tiempo_visita": 296.0
31},
32];
../../_images/Reportes17.png

Estructura CSS#

La estructura de un archivo CSS es simple y básica, son estilos generales aplicados especialmente a los títulos de los elementos. Utilice el siguiente código como base para sus reportes futuros.

Nota

La mayoría de los estilos del reporte dependen de la herramienta que se esté utilizando, ya que estas contienen sus propios estilos.

 1.title_tables h3 {
 2color: black;
 3font: 33px gothambook;
 4margin-top: 30px;
 5text-align: left;
 6}
 7
 8
 9.hrFirstElement {
10border-top: 1px solid #707b7c;
11width: 500px;
12margin-left: 0%;
13}
14
15.hrSecondElement {
16border-top: 1px solid #707b7c;
17width: 550px;
18margin-left: 0%;
19}
20
21body{
22font-family: gothambook;
23}

En esta sección ha aprendido lo necesario para desarrollar sus reportes demo. Por favor, continúe con la siguiente parte para desarrollar el script necesario y construir las consultas a la base de datos y poblar sus elementos con datos reales.