La biblioteca de componentes DataV, construida sobre Vue.js, permite crear interfaces de visualización de datos de alto rendimiento. Un desafío común en entornos de monitoreo industrial es mantener la operatividad de los tableros durante interrupciones de red. Este artículo detalla cómo implementar sincronización de datos offline utilizando IndexedDB dentro de una aplicación DataV.
Necesidad de Persistencia de Datos Local
Los tableros de control en sectores como manufactura o servicios públicos requieren disponibilidad continua. Las fluctuaciones de red pueden causar fallos en la carga de datos críticos. Implementar un mecanismo de cache local garantiza que los indicadores esenciales permanezcan visibles y actualizados, mejorando la resiliencia del sistema.
Ventajas de IndexedDB sobre Alternativas de Almacenamiento
- Capacidad de almacenamiento: Soporta varios gigabytes, superando ampliamente los límites de localStorage (aproximadamente 5MB).
- Consultas complejas: Permite definir índices y realizar operaciones transaccionales.
- Naturaleza asíncrona: Las operaciones no bloquean el hilo principle, ideal para conjuntos de datos voluminosos.
- Soporte para binarios: Capaz de almacenar archivos e imágenes directamente.
Implementación de la Capa de Persistencia
DataV no proporciona un envoltorio para IndexedDB, por lo que se requiere crear una utilidad personalizada. A continuación, se presenta una clase reestructurada con una lógica diferente y nombres de variables modificados.
// Utilidad para manejo de base de datos local
class LocalStorageHelper {
constructor(databaseId, collectionName) {
this.databaseId = databaseId;
this.collectionName = collectionName;
this.connection = null;
}
async establishConnection() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.databaseId, 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains(this.collectionName)) {
db.createObjectStore(this.collectionName, { keyPath: 'id' });
}
};
request.onsuccess = (event) => {
this.connection = event.target.result;
resolve(this.connection);
};
request.onerror = (event) => reject(event.target.error);
});
}
async persistRecord(record) {
if (!this.connection) await this.establishConnection();
const transaction = this.connection.transaction(this.collectionName, 'readwrite');
const store = transaction.objectStore(this.collectionName);
store.put(record);
return new Promise((resolve, reject) => {
transaction.oncomplete = () => resolve();
transaction.onerror = () => reject(transaction.error);
});
}
async fetchRecord(identifier) {
if (!this.connection) await this.establishConnection();
const transaction = this.connection.transaction(this.collectionName, 'readonly');
const store = transaction.objectStore(this.collectionName);
const request = store.get(identifier);
return new Promise((resolve, reject) => {
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
}
Integración con un Componente DataV
Se utiliza el componente DvScrollBoard para mostrar datos de una tabla. La lógica intenta primero obtener los datos del servidor; si falla, recurre a la versión cacheada localmente.
<template>
<dv-scroll-board :config="tableConfig" style="width:100%;height:300px" />
</template>
<script>
import { ScrollBoard } from '@jiaminghi/data-view'
import LocalStorageHelper from '@/utils/localStorageHelper'
export default {
components: {
DvScrollBoard: ScrollBoard
},
data() {
return {
tableConfig: { data: [] },
dbHelper: null
}
},
async mounted() {
this.dbHelper = new LocalStorageHelper('metricsDB', 'tableData');
await this.refreshTableData();
},
methods: {
async refreshTableData() {
let dataset = null;
try {
dataset = await this.fetchRemoteData();
await this.dbHelper.persistRecord({ id: 'currentTable', payload: dataset });
} catch (networkError) {
console.warn('Fallo de red, recuperando datos locales...');
const cachedRecord = await this.dbHelper.fetchRecord('currentTable');
if (cachedRecord) {
dataset = cachedRecord.payload;
}
}
if (dataset) {
this.tableConfig = { ...this.tableConfig, data: dataset };
}
},
fetchRemoteData() {
return new Promise((resolve, reject) => {
// Simulación de llamada API
setTimeout(() => {
resolve([
['Indicador A', '1452'],
['Indicador B', '987'],
['Indicador C', '2304']
]);
}, 500);
});
}
}
}
</script>
Estrategias de Optimización
- Política de actualización: Implementar actualizaciones incrementales para minimizar el tráfico de red.
- Gestión de caché: Establecer un ciclo de vida para los datos almacenados y purgar entradas obsoletas periódicamente.
- Manejo de fallos: Registrar errores de sincronización y proveer un mecanismo para reintento manual.
Estructura de la Biblioteca DataV
Los componentes principales residen en src/components/ y incluyen visualizaciones como:
ActiveRingChart(Gráfico de anillo animado)CapsuleChart(Gráfico de cápsulas)DigitalFlop(Contador digital)
La utilidad para IndexedDB debe ubicarse convencionalmente en el directorio src/utils/ o src/services/.