Skip to content

05_02_07 - Export Formats Module

📋 Descripción General

Motor de exportación multi-formato para grafos de dependencias. Permite interoperabilidad con herramientas externas de análisis de grafos (Gephi, Cytoscape, NetworkX, igraph, R) y generación de reportes.

🎯 Objetivos

  1. Exportar a 6+ formatos estándar de la industria
  2. Preservar toda la metadata (CPU, latencia, jerarquía, estado)
  3. Validación de importación para verificar integridad
  4. Exportación por lotes de múltiples vistas filtradas
  5. Performance para grafos de 500+ nodos en <100ms

🏗️ Arquitectura

ExportEngine
├── IGraphExporter (interface base)
├── DotExporter        → GraphViz (.dot)
├── GmlExporter        → Graph Modelling Language (.gml)
├── GraphMlExporter    → XML-based format (.graphml)
├── JsonExporter       → JSON format (.json)
├── MermaidExporter    → Markdown diagrams (.mmd)
├── CsvExporter        → Tabular data (nodes.csv + edges.csv)
├── BatchExporter      → Exportación multi-formato
└── ImportValidator    → Verificación de integridad

📊 Formatos Soportados

Formato Extensión Herramientas Compatibles Uso Típico
DOT .dot GraphViz, Doxygen Visualización estática
GML .gml Gephi, Cytoscape, yEd Análisis interactivo
GraphML .graphml Gephi, NetworkX, igraph Análisis científico
JSON .json D3.js, Custom tools Web/API
Mermaid .mmd GitHub, GitLab, MkDocs Documentación
CSV .csv Excel, R, Python pandas Análisis estadístico

🔧 Uso

Exportación Básica

#include "export_engine.hpp"

// Construir grafo
Graph graph = /* ... */;

// Exportar a GraphViz
DotExporter dot_exporter;
std::string dot_content = dot_exporter.export_graph(graph);
std::ofstream("dependencies.dot") << dot_content;

// Exportar a GML para Gephi
GmlExporter gml_exporter;
std::string gml_content = gml_exporter.export_graph(graph);
std::ofstream("dependencies.gml") << gml_content;

// Exportar a CSV para análisis en R
CsvExporter csv_exporter;
auto [nodes_csv, edges_csv] = csv_exporter.export_graph_csv(graph);
std::ofstream("nodes.csv") << nodes_csv;
std::ofstream("edges.csv") << edges_csv;

Exportación por Lotes

#include "export_engine.hpp"

BatchExporter batch;

// Configurar exportación múltiple
batch.add_format(ExportFormat::DOT)
     .add_format(ExportFormat::GML)
     .add_format(ExportFormat::JSON)
     .set_output_directory("exports/");

// Exportar grafo completo
batch.export_all(graph, "full_graph");

// Exportar vista filtrada
auto filter = FilterChain().by_level({L2_CELL, L3_ENGINE});
Graph filtered = filter.apply(graph);
batch.export_all(filtered, "cells_and_engines");

// Resultado:
// exports/full_graph.dot
// exports/full_graph.gml
// exports/full_graph.json
// exports/cells_and_engines.dot
// exports/cells_and_engines.gml
// exports/cells_and_engines.json

Validación de Importación

#include "export_engine.hpp"

// Exportar
DotExporter exporter;
std::string dot_content = exporter.export_graph(original_graph);

// Importar (hipotético)
Graph imported_graph = import_from_dot(dot_content);

// Validar integridad
ImportValidator validator;
ValidationReport report = validator.validate(original_graph, imported_graph);

if (report.is_valid) {
    std::cout << "✓ Exportación/Importación exitosa\n";
    std::cout << "  Nodos: " << report.matched_nodes << "/" << report.total_nodes << "\n";
    std::cout << "  Aristas: " << report.matched_edges << "/" << report.total_edges << "\n";
} else {
    std::cerr << "✗ Fallos de validación:\n";
    for (const auto& error : report.errors) {
        std::cerr << "  - " << error << "\n";
    }
}

📐 Casos de Uso Prácticos

1. Análisis de Comunidades en Gephi

// Exportar a GML con metadata para detección de comunidades
GmlExporter gml;
gml.set_option("include_cpu_weight", true);
gml.set_option("include_hierarchy_attribute", true);

std::string gml_content = gml.export_graph(graph);
save_to_file("for_gephi.gml", gml_content);

Workflow en Gephi: 1. File → Open → for_gephi.gml 2. Statistics → Modularity (para detectar clusters) 3. Layout → ForceAtlas 2 (usa CPU como peso) 4. Partition → Hierarchy Level (colorear por jerarquía)

2. Análisis de Centralidad en NetworkX (Python)

// Exportar a GraphML para análisis en Python
GraphMlExporter graphml;
graphml.set_option("include_all_properties", true);

std::string xml = graphml.export_graph(graph);
save_to_file("for_networkx.graphml", xml);

Análisis en Python:

import networkx as nx

G = nx.read_graphml("for_networkx.graphml")

# Calcular PageRank (importancia de nodos)
pagerank = nx.pagerank(G)
top_10 = sorted(pagerank.items(), key=lambda x: x[1], reverse=True)[:10]

# Detectar cuellos de botella
betweenness = nx.betweenness_centrality(G)
bottlenecks = [node for node, b in betweenness.items() if b > 0.5]

# Exportar resultados
import pandas as pd
df = pd.DataFrame({
    'node': list(pagerank.keys()),
    'pagerank': list(pagerank.values()),
    'betweenness': [betweenness[n] for n in pagerank.keys()]
})
df.to_csv("analysis_results.csv")

3. Documentación Automática con Mermaid

// Exportar a Mermaid para documentación en GitHub
MermaidExporter mermaid;
mermaid.set_option("max_nodes", 30);  // Limitar para legibilidad
mermaid.set_option("orientation", "TD");  // Top-Down

auto filter = FilterChain().by_level({L3_ENGINE});
Graph engines_only = filter.apply(graph);

std::string mermaid_code = mermaid.export_graph(engines_only);

// Integrar en README.md
std::ofstream readme("README.md", std::ios::app);
readme << "\n## Arquitectura de Engines\n\n";
readme << "```mermaid\n";
readme << mermaid_code;
readme << "\n```\n";

4. Análisis Estadístico en R

// Exportar a CSV para análisis estadístico
CsvExporter csv;
auto [nodes_csv, edges_csv] = csv.export_graph_csv(graph);

save_to_file("nodes.csv", nodes_csv);
save_to_file("edges.csv", edges_csv);

Análisis en R:

library(dplyr)
library(ggplot2)
library(igraph)

# Cargar datos
nodes <- read.csv("nodes.csv")
edges <- read.csv("edges.csv")

# Crear grafo
g <- graph_from_data_frame(edges, vertices = nodes, directed = TRUE)

# Análisis de distribución de grados
degree_dist <- degree(g, mode = "all")
qplot(degree_dist, geom = "histogram", bins = 20) +
  labs(title = "Distribución de Grados", x = "Grado", y = "Frecuencia")

# Correlación CPU vs Grado
cor_data <- data.frame(
  degree = degree(g),
  cpu = nodes$cpu_cycles
)
ggplot(cor_data, aes(x = degree, y = cpu)) +
  geom_point() +
  geom_smooth(method = "lm") +
  labs(title = "CPU vs Grado de Conectividad")

# Detectar componentes fuertemente conectados
scc <- components(g, mode = "strong")
cat("Componentes fuertemente conectados:", scc$no, "\n")

🎨 Características de Exportadores

DotExporter (GraphViz)

  • ✅ Sintaxis DOT con atributos personalizados
  • ✅ Colorización automática por jerarquía
  • ✅ Shapes según categoría (box, ellipse, hexagon, diamond)
  • ✅ Edge labels con CPU/latencia
  • ✅ Clusters para agrupar por nivel
  • ✅ Soporte para rankdir (TB, LR, BT, RL)

GmlExporter (Gephi/Cytoscape)

  • ✅ Formato GML estándar
  • ✅ Metadata como atributos de nodo/arista
  • ✅ Soporte para grafos dirigidos
  • ✅ Coordenadas iniciales (si existen)
  • ✅ Compatibilidad con Gephi 0.9+

GraphMlExporter (NetworkX/igraph)

  • ✅ XML Schema válido
  • ✅ Atributos tipados (int, double, string, boolean)
  • ✅ Metadata en definitions
  • ✅ Soporte para grafos mixtos (directed/undirected)
  • ✅ Namespace estándar GraphML

JsonExporter (D3.js/APIs)

  • ✅ Formato nodes/links estándar de D3.js
  • ✅ Metadata completa preservada
  • ✅ Pretty-print opcional
  • ✅ Compatibilidad con vis.js, cytoscape.js

MermaidExporter (Documentación)

  • ✅ Sintaxis Mermaid v10+
  • ✅ Subgraphs por jerarquía
  • ✅ Estilos CSS personalizados
  • ✅ Truncamiento inteligente para grafos grandes
  • ✅ Click handlers para interactividad

CsvExporter (Análisis Estadístico)

  • ✅ Separación nodes.csv + edges.csv
  • ✅ Headers descriptivos
  • ✅ Escape correcto de caracteres especiales
  • ✅ Formato compatible con Excel/R/Python pandas
  • ✅ Opcional: adjacency matrix CSV

🔍 Validación de Integridad

El ImportValidator verifica que la exportación/importación preserva:

  1. Estructura del grafo
  2. Mismo número de nodos y aristas
  3. Mismas conexiones (isomorfismo)

  4. Metadata de nodos

  5. UUIDs
  6. Nombres
  7. Jerarquía
  8. CPU cycles
  9. Latencia
  10. Categoría
  11. Estado

  12. Metadata de aristas

  13. Nodos origen/destino
  14. Tipo de dependencia

  15. Propiedades topológicas

  16. Grados de entrada/salida
  17. Componentes conexos
  18. Ciclos (si existen)

📈 Performance

Benchmarks en grafo de 500 nodos, 1200 aristas:

Formato Tiempo Export Tamaño Archivo Tiempo Import*
DOT 12 ms 85 KB N/A
GML 18 ms 120 KB 45 ms
GraphML 25 ms 210 KB 52 ms
JSON 8 ms 95 KB 15 ms
Mermaid 10 ms 45 KB N/A
CSV 6 ms 65 KB (total) 20 ms

*Import realizado por herramientas externas (NetworkX, igraph)

🚀 Optimizaciones

  1. String Builders: std::ostringstream con reserva de capacidad
  2. Escape Caching: Cache de strings escapados frecuentes
  3. Parallel Export: Exportación concurrente de múltiples formatos
  4. Streaming: Escritura directa a archivo para grafos muy grandes
  5. Compression: Opcional gzip para reducir tamaño

📝 Próximos Pasos (Extensiones Futuras)

  • GEXF Exporter (Gephi native format)
  • Pajek NET Exporter (análisis de redes sociales)
  • TGF Exporter (Trivial Graph Format)
  • Cytoscape.js JSON (formato específico)
  • Neo4j Cypher (import a base de datos de grafos)
  • Excel XLSX (con múltiples hojas: nodes, edges, stats)
  • PDF/PNG Rendering (usando GraphViz internamente)

🔗 Interoperabilidad

Este módulo es clave para integrar con el ecosistema de análisis de grafos:

  • Gephi: Análisis visual interactivo, detección de comunidades
  • Cytoscape: Análisis de redes biológicas (aplicable a DSP)
  • NetworkX: Algoritmos avanzados en Python
  • igraph: Performance en R/Python/C
  • GraphTool: Análisis estadístico de redes
  • Neo4j: Base de datos de grafos para queries complejas

📚 Referencias


Parte de: 05_02_DEPENDENCY_GRAPH - Dependency Graph Visualizer Requiere: graph.hpp, nlohmann/json Exporta: export_engine.hpp