UNPKG

datajunction-ui

Version:

DataJunction Metrics Platform UI

140 lines (132 loc) 4.08 kB
import { useContext } from 'react'; import { MarkerType } from 'reactflow'; import '../../../styles/dag.css'; import 'reactflow/dist/style.css'; import DJClientContext from '../../providers/djclient'; import LayoutFlow from '../../components/djgraph/LayoutFlow'; const NodeGraphTab = djNode => { const djClient = useContext(DJClientContext).DataJunctionAPI; const createNode = node => { const primary_key = node.columns .filter(col => col.attributes.some(attr => attr.attribute_type.name === 'primary_key'), ) .map(col => col.name); const dimensionLinkForeignKeys = node.dimension_links ? node.dimension_links.flatMap(link => Object.keys(link.foreign_keys).map(key => key.split('.').slice(-1)), ) : []; const column_names = node.columns .map(col => { return { name: col.name, type: col.type, dimension: col.dimension !== null ? col.dimension.name : null, order: primary_key.includes(col.name) ? -1 : dimensionLinkForeignKeys.includes(col.name) ? 0 : 1, }; }) .sort((a, b) => a.order - b.order); return { id: String(node.name), type: 'DJNode', data: { label: node.table !== null ? String(node.schema_ + '.' + node.table) : 'default.' + node.name, table: node.table, name: String(node.name), display_name: String(node.display_name), type: node.type, primary_key: primary_key, column_names: column_names, is_current: node.name === djNode.djNode.name, }, }; }; const dimensionEdges = node => { return node.dimension_links === undefined ? [] : node.dimension_links.flatMap(link => { return Object.keys(link.foreign_keys).map(fk => { return { id: link.dimension.name + '->' + node.name + '=' + link.foreign_keys[fk] + '->' + fk, source: link.dimension.name, sourceHandle: link.foreign_keys[fk], target: node.name, targetHandle: fk, draggable: true, markerStart: { type: MarkerType.Arrow, width: 20, height: 20, color: '#b0b9c2', }, style: { strokeWidth: 3, stroke: '#b0b9c2', }, }; }); }); }; const parentEdges = node => { return node.parents .filter(parent => parent.name) .map(parent => { return { id: node.name + '-' + parent.name, source: parent.name, sourceHandle: parent.name, target: node.name, targetHandle: node.name, animated: true, markerEnd: { type: MarkerType.Arrow, }, style: { strokeWidth: 3, stroke: '#b0b9c2', }, }; }); }; const dagFetch = async (getLayoutedElements, setNodes, setEdges) => { let related_nodes = djNode.djNode ? await djClient.node_dag(djNode.djNode.name) : []; var djNodes = djNode.djNode ? [djNode.djNode] : []; for (const iterable of [related_nodes]) { for (const item of iterable) { if (item.type !== 'cube') { djNodes.push(item); } } } let edges = []; djNodes.forEach(node => { edges = edges.concat(parentEdges(node)); edges = edges.concat(dimensionEdges(node)); }); const nodes = djNodes.map(node => createNode(node)); // use dagre to determine the position of the parents (the DJ nodes) // the positions of the columns are relative to each DJ node getLayoutedElements(nodes, edges); setNodes(nodes); setEdges(edges); }; return LayoutFlow(djNode, dagFetch); }; export default NodeGraphTab;