/**
* @file Creation of edges according to the AntV specification
* @module @@graph/Edge
*/
import G6 from '@antv/g6';
import { flatten, values, concat, path, assocPath } from 'ramda';
import {entityTypes} from '@@constants/entity-types';
import {Edge as EdgeWrapper} from '@@graph/wrappers';
const EDGE_TYPE = 'graphEdge';
export const Edge = data => ({
...data,
type: EDGE_TYPE
});
const getPropertyIds = ({sourceId, targetId}, objProperties = {}) => Object.entries(objProperties)
.reduce((acc, [predicate, targets]) =>
acc.concat(targets
.filter(t => t === targetId)
.map(target => `property_${sourceId}-${predicate}-${target}`)
), []);
export const getEdges = data => {
let existingEdges = {};
const res = Object.entries(data).map(([sourceId, {objectProperties}]) => {
const targets = values(objectProperties).reduce(concat, []);
return values(targets.reduce((acc, targetId) => {
// Prevent duplicates for the same source-target pair
if (sourceId === targetId || path([sourceId, targetId], existingEdges) || path([targetId, sourceId], existingEdges)) {
return acc;
}
existingEdges = assocPath([sourceId, targetId], true, existingEdges);
return Object.assign(acc, {
[targetId]: Edge({
source: sourceId,
target: targetId,
propertyIds: getPropertyIds({sourceId, targetId}, objectProperties).concat(getPropertyIds({sourceId: targetId, targetId: sourceId}, path([targetId, 'objectProperties'], data))),
data: {
source: sourceId,
target: targetId,
type: entityTypes.edge
}
})
})
}, {}));
});
return flatten(res);
}
G6.registerEdge(EDGE_TYPE, {
afterDraw(cfg, {cfg: {item}}) {
item.set('wrapper', new EdgeWrapper(item));
}
}, 'line');