/** * Adapta el modelo de grafo de provenance ({ id, kind, label, image, entity } * y { from, to, certain }) al formato de vis-network, incluyendo la semántica * de certeza: arista cierta = sólida, arista dudosa = discontinua. */ const COLORS = { product: '#26a69a', supplier: '#42a5f5', organization: '#ffb74d', municipality: '#66bb6a', department: '#5c6bc0', country: '#ab47bc', junction: '#78909c', } const PRODUCT_SPACING = 110 const COLUMN_X = { product: -240, junction: -160, supplier: -80, organization: 80, municipality: 240, department: 400, country: 560, } export function toVisNodes (nodes) { const products = nodes.filter(node => node.kind === 'product') const productY = new Map() products.forEach((node, index) => { productY.set(node.entity.id, (index - (products.length - 1) / 2) * PRODUCT_SPACING) }) return nodes.map(node => { const color = COLORS[node.kind] || '#cfd8dc' const { image, ...rest } = node if (node.kind === 'junction') { return { ...rest, shape: 'dot', color, size: 10, label: '', x: COLUMN_X.junction, y: productY.get(node.entity.id), fixed: { x: true, y: true }, } } const base = image ? { ...rest, image, shape: 'circularImage', borderWidth: 2 } : { ...rest, shape: 'dot', color, borderWidth: 2 } if (node.kind === 'product') { return { ...base, x: COLUMN_X.product, y: productY.get(node.entity.id), fixed: { x: true, y: true }, } } return { ...base, x: COLUMN_X[node.kind], fixed: { x: true, y: false } } }) } export function toVisEdges (edges) { return edges.map(edge => ({ from: edge.from, to: edge.to, dashes: !edge.certain, })) } export const chartOptions = { nodes: { font: { size: 13, color: '#263238' } }, edges: { color: { color: '#546e7a' } }, physics: { barnesHut: { gravitationalConstant: -4000, springLength: 120, springConstant: 0.02 }, }, }