import { SchemaReactflowNodeWithFunctions, SchemaReactflowRelationWithFunctions } from '../model/reactflow'; import Graph from 'graphology'; import { Attributes } from 'graphology-types'; import { MarkerType, Edge, Node } from 'reactflow'; import { QueryElementTypes } from '../../querybuilder'; import { SchemaGraphology } from '../model'; //TODO does not belong here; maybe should go into the GraphPolarisThemeProvider export function schemaExpandRelation(graph: SchemaGraphology): SchemaGraphology { const newGraph = graph.copy(); newGraph.forEachNode((node, attributes) => { newGraph.mergeNodeAttributes(node, { type: QueryElementTypes.Entity }); }); //makeNewRelationNodes graph.forEachEdge((edge, attributes, source, target): void => { const newID = 'RelationNode:' + edge; newGraph.addNode(newID, { ...attributes, name: edge, label: edge, attributes: { ...attributes.attributes }, x: 0, y: 0, type: QueryElementTypes.Relation, }); const id = 'RelationEdge' + source + '->' + newID; newGraph.addDirectedEdgeWithKey(id, source, newID, { name: edge, }); const id2 = 'RelationEdge' + newID + '->' + target; newGraph.addDirectedEdgeWithKey(id2, newID, target, {}); newGraph.dropEdge(edge); }); return newGraph; } // Takes the schema as an input and creates basic react flow elements for them. export function schemaGraphology2Reactflow( graph: Graph, defaultEdgeType: string, animatedEdges = false, ): { nodes: Array<Node<SchemaReactflowNodeWithFunctions | SchemaReactflowRelationWithFunctions>>; edges: Array<Edge>; } { const initialElements: { nodes: Array<Node>; edges: Array<Edge> } = { nodes: [], edges: [], }; initialElements.nodes = createReactFlowNodes(graph); initialElements.edges = createReactFlowEdges(graph, defaultEdgeType, animatedEdges); return initialElements; } export function createReactFlowNodes(graph: Graph): Array<Node> { const nodeElements: Array<Node> = []; graph.forEachNode((node: string, attributes: Attributes): void => { if (!Array.isArray(attributes.attributes)) { attributes.attributes = Object.values(attributes.attributes); } const newNode: Node = { id: node, data: { ...attributes, }, position: { x: attributes.x, y: attributes.y }, type: attributes.type, }; nodeElements.push(newNode); }); return nodeElements; } export function createReactFlowEdges(graph: Graph, defaultEdgeType: string, animatedEdges = false): Array<Edge> { const edgeElements: Array<Edge> = []; graph.forEachEdge((edge, attributes, source, target): void => { const newEdge: Edge = { id: edge, source: source, target: target, data: { ...attributes, }, // label: edge, type: attributes?.type || defaultEdgeType, animated: animatedEdges, markerEnd: MarkerType.ArrowClosed, // TODO: Check }; edgeElements.push(newEdge); }); return edgeElements; }