#49 feat: graficos de provenance en columnas por nivel y aristas deduplicadas
This commit is contained in:
@@ -17,6 +17,7 @@ function makeCollector () {
|
||||
const nodes = []
|
||||
const edges = []
|
||||
const seen = new Map()
|
||||
const edgeSeen = new Map()
|
||||
return {
|
||||
nodes,
|
||||
edges,
|
||||
@@ -36,7 +37,14 @@ function makeCollector () {
|
||||
return seen.get(id)
|
||||
},
|
||||
addEdge (from, to, certain) {
|
||||
edges.push({ from, to, certain: Boolean(certain) })
|
||||
const key = `${from}\u0000${to}`
|
||||
if (edgeSeen.has(key)) {
|
||||
edgeSeen.get(key).certain = edgeSeen.get(key).certain && Boolean(certain)
|
||||
return
|
||||
}
|
||||
const edge = { from, to, certain: Boolean(certain) }
|
||||
edgeSeen.set(key, edge)
|
||||
edges.push(edge)
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -97,7 +105,6 @@ export function buildTerritoryGraph (provenance) {
|
||||
|
||||
const municipalityCertain = isCertain(distinctValues(relations.map(rel => rel.municipality)))
|
||||
const departmentCertain = isCertain(distinctValues(relations.map(rel => rel.department)))
|
||||
const countryCertain = isCertain(distinctValues(relations.map(rel => rel.country)))
|
||||
|
||||
for (const rel of relations) {
|
||||
if (!rel.municipality) continue
|
||||
@@ -110,12 +117,6 @@ export function buildTerritoryGraph (provenance) {
|
||||
const department = collector.addNode('department', rel.department)
|
||||
collector.addEdge(municipality.id, department.id, departmentCertain)
|
||||
}
|
||||
for (const rel of relations) {
|
||||
if (!rel.department || !rel.country) continue
|
||||
const department = collector.addNode('department', rel.department)
|
||||
const country = collector.addNode('country', rel.country)
|
||||
collector.addEdge(department.id, country.id, countryCertain)
|
||||
}
|
||||
}
|
||||
return { nodes: collector.nodes, edges: collector.edges }
|
||||
}
|
||||
@@ -127,7 +128,7 @@ export function hasAnySupplier (provenance) {
|
||||
export function hasAnyTerritory (provenance) {
|
||||
return (provenance || []).some(entry =>
|
||||
(entry.suppliers || []).some(rel =>
|
||||
rel.municipality || rel.department || rel.country
|
||||
rel.municipality || rel.department
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,17 +14,49 @@ const COLORS = {
|
||||
junction: '#78909c',
|
||||
}
|
||||
|
||||
const PRODUCT_SPACING = 110
|
||||
const COLUMN_X = {
|
||||
product: -240,
|
||||
junction: -120,
|
||||
supplier: 0,
|
||||
organization: 240,
|
||||
municipality: 240,
|
||||
department: 480,
|
||||
}
|
||||
|
||||
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: '' }
|
||||
return {
|
||||
...rest,
|
||||
shape: 'dot',
|
||||
color,
|
||||
size: 10,
|
||||
label: '',
|
||||
x: COLUMN_X.junction,
|
||||
y: productY.get(node.entity.id),
|
||||
fixed: { x: true, y: true },
|
||||
}
|
||||
}
|
||||
if (image) {
|
||||
return { ...rest, image, shape: 'circularImage', borderWidth: 2 }
|
||||
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 { ...rest, shape: 'dot', color, borderWidth: 2 }
|
||||
return { ...base, x: COLUMN_X[node.kind], fixed: { x: true, y: false } }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user