162 lines
5.4 KiB
Text
Executable file
162 lines
5.4 KiB
Text
Executable file
// Importación de ForceGraph3D
|
|
import ForceGraph3D from './libs/3d-force-graph.min.js'; // Asegúrate de que está en la carpeta libs
|
|
|
|
// Importación del cliente de Elasticsearch
|
|
import { Client } from 'https://cdn.skypack.dev/@elastic/elasticsearch';
|
|
|
|
// Configuración de la conexión a Elasticsearch
|
|
const client = new Client({ node: 'http://localhost:9200' });
|
|
|
|
// Definir la clase Graph
|
|
class Graph {
|
|
constructor(containerId) {
|
|
this.graph = ForceGraph3D()(document.getElementById(containerId));
|
|
this.maxNodes = 200; // Número máximo de nodos a mostrar
|
|
this.minSimilarity = 5; // Umbral mínimo de similitud
|
|
}
|
|
|
|
// Configuración del número máximo de nodos
|
|
setMaxNodes(maxNodes) {
|
|
this.maxNodes = maxNodes;
|
|
}
|
|
|
|
// Configuración del umbral de similitud
|
|
setMinSimilarity(minSimilarity) {
|
|
this.minSimilarity = minSimilarity;
|
|
}
|
|
|
|
// Cargar nodos desde Elasticsearch
|
|
async loadNodes(subtematica = '', palabraClave = '', fechaInicio = '', fechaFin = '') {
|
|
const query = {
|
|
bool: {
|
|
must: [
|
|
{ match: { tema: 'corporaciones y organizaciones internacionales' } }
|
|
],
|
|
filter: []
|
|
}
|
|
};
|
|
|
|
if (subtematica) {
|
|
query.bool.must.push({ match: { subtema: subtematica } });
|
|
}
|
|
|
|
if (palabraClave) {
|
|
query.bool.must.push({ match: { contenido: palabraClave } });
|
|
}
|
|
|
|
if (fechaInicio && fechaFin) {
|
|
query.bool.filter.push({
|
|
range: {
|
|
fecha: {
|
|
gte: fechaInicio,
|
|
lte: fechaFin
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
const response = await client.search({
|
|
index: 'informacion', // Usamos el índice correcto
|
|
body: {
|
|
query: query,
|
|
size: this.maxNodes,
|
|
sort: { importancia: 'desc' }
|
|
}
|
|
});
|
|
|
|
return response.body.hits.hits.map(hit => ({
|
|
id: hit._source.nombre_archivo,
|
|
group: hit._source.tipo_archivo,
|
|
tema: hit._source.tema,
|
|
content: hit._source.contenido,
|
|
fecha: hit._source.fecha
|
|
}));
|
|
}
|
|
|
|
// Cargar relaciones directamente desde Elasticsearch
|
|
async loadLinks() {
|
|
const response = await client.search({
|
|
index: 'informacion', // Asegurarse de que el índice correcto se utiliza para las relaciones
|
|
body: {
|
|
query: {
|
|
match_all: {} // Obtenemos todas las relaciones almacenadas
|
|
},
|
|
size: this.maxNodes // Limitamos el tamaño de la respuesta
|
|
}
|
|
});
|
|
|
|
const links = response.body.hits.hits.map(hit => {
|
|
const content = hit._source.contenido;
|
|
const lines = content.split('\n'); // Asumiendo que las relaciones están en formato línea por línea
|
|
|
|
return lines.map(line => {
|
|
const [source, target, similarity] = line.split(',');
|
|
if (parseFloat(similarity) >= this.minSimilarity) {
|
|
return {
|
|
source: path.basename(source.trim(), '.txt'),
|
|
target: path.basename(target.trim(), '.txt'),
|
|
value: parseFloat(similarity)
|
|
};
|
|
}
|
|
}).filter(link => link); // Filtramos los enlaces válidos
|
|
});
|
|
|
|
return links.flat();
|
|
}
|
|
|
|
// Crear datos del gráfico
|
|
createGraphData(nodes, links) {
|
|
return {
|
|
nodes,
|
|
links
|
|
};
|
|
}
|
|
|
|
// Mostrar el contenido de un nodo al hacer clic
|
|
async showNodeContent(node) {
|
|
try {
|
|
const response = await client.search({
|
|
index: 'informacion',
|
|
body: {
|
|
query: {
|
|
match: { nombre_archivo: node.id }
|
|
}
|
|
},
|
|
size: 1
|
|
});
|
|
|
|
const content = response.body.hits.hits[0]._source.contenido;
|
|
const contentDiv = document.getElementById('contentDisplay');
|
|
contentDiv.innerText = content || "No hay contenido disponible.";
|
|
} catch (error) {
|
|
console.error("Error al obtener contenido:", error);
|
|
const contentDiv = document.getElementById('contentDisplay');
|
|
contentDiv.innerText = "Error al obtener contenido.";
|
|
}
|
|
}
|
|
|
|
// Dibujar el gráfico
|
|
async drawGraph(subtematica = '', palabraClave = '', fechaInicio = '', fechaFin = '') {
|
|
const nodes = await this.loadNodes(subtematica, palabraClave, fechaInicio, fechaFin);
|
|
const links = await this.loadLinks(); // Cargamos las relaciones desde Elasticsearch
|
|
const graphData = this.createGraphData(nodes, links);
|
|
|
|
this.graph
|
|
.graphData(graphData)
|
|
.backgroundColor('black')
|
|
.nodeLabel('id')
|
|
.nodeAutoColorBy('group')
|
|
.nodeVal(5)
|
|
.linkColor(() => 'yellow')
|
|
.onNodeClick(node => {
|
|
this.showNodeContent(node);
|
|
})
|
|
.forceEngine('d3')
|
|
.d3Force('charge').strength(-200)
|
|
.d3Force('link').distance(50);
|
|
}
|
|
}
|
|
|
|
// Inicializar el gráfico
|
|
const myGraph = new Graph('canvasContainer');
|
|
myGraph.drawGraph();
|