2022-10-06 19:41:18 -04:00
|
|
|
import React, { useContext } from 'react';
|
2021-04-03 11:13:25 -07:00
|
|
|
import { Group } from '@vx/group';
|
2021-04-06 18:21:33 -07:00
|
|
|
import { TransformMatrix } from '@vx/zoom/lib/types';
|
2021-04-03 11:13:25 -07:00
|
|
|
|
2022-12-20 10:54:08 -05:00
|
|
|
import { NodeData, EntitySelectParams, TreeProps, VizNode, VizEdge, EntityAndType, UpdatedLineages } from './types';
|
2021-04-03 11:13:25 -07:00
|
|
|
import LineageEntityNode from './LineageEntityNode';
|
2023-02-02 15:30:49 -08:00
|
|
|
import LineageEntityEdge from './LineageEntityEdge';
|
2022-10-06 19:41:18 -04:00
|
|
|
import { LineageExplorerContext } from './utils/LineageExplorerContext';
|
2021-04-03 11:13:25 -07:00
|
|
|
|
|
|
|
type Props = {
|
2021-10-22 15:46:46 -07:00
|
|
|
data: NodeData;
|
2021-04-03 11:13:25 -07:00
|
|
|
zoom: {
|
2021-04-06 18:21:33 -07:00
|
|
|
transformMatrix: TransformMatrix;
|
2021-04-03 11:13:25 -07:00
|
|
|
};
|
|
|
|
onEntityClick: (EntitySelectParams) => void;
|
2021-04-23 00:18:39 -07:00
|
|
|
onEntityCenter: (EntitySelectParams) => void;
|
2022-05-23 17:21:30 -04:00
|
|
|
onLineageExpand: (data: EntityAndType) => void;
|
2021-04-03 11:13:25 -07:00
|
|
|
selectedEntity?: EntitySelectParams;
|
2021-10-22 15:46:46 -07:00
|
|
|
hoveredEntity?: EntitySelectParams;
|
|
|
|
setHoveredEntity: (EntitySelectParams) => void;
|
|
|
|
onDrag: (params: EntitySelectParams, event: React.MouseEvent) => void;
|
2021-04-03 11:13:25 -07:00
|
|
|
margin: TreeProps['margin'];
|
2021-10-22 15:46:46 -07:00
|
|
|
nodesToRender: VizNode[];
|
|
|
|
edgesToRender: VizEdge[];
|
|
|
|
nodesByUrn: Record<string, VizNode>;
|
2022-12-20 10:54:08 -05:00
|
|
|
setUpdatedLineages: React.Dispatch<React.SetStateAction<UpdatedLineages>>;
|
2021-04-03 11:13:25 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
function transformToString(transform: {
|
|
|
|
scaleX: number;
|
|
|
|
scaleY: number;
|
|
|
|
translateX: number;
|
|
|
|
translateY: number;
|
|
|
|
skewX: number;
|
|
|
|
skewY: number;
|
|
|
|
}): string {
|
|
|
|
return `matrix(${transform.scaleX}, ${transform.skewX}, ${transform.skewY}, ${transform.scaleY}, ${transform.translateX}, ${transform.translateY})`;
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function LineageTreeNodeAndEdgeRenderer({
|
2021-10-22 15:46:46 -07:00
|
|
|
data,
|
2021-04-03 11:13:25 -07:00
|
|
|
zoom,
|
|
|
|
margin,
|
|
|
|
onEntityClick,
|
2021-04-23 00:18:39 -07:00
|
|
|
onEntityCenter,
|
2021-04-03 11:13:25 -07:00
|
|
|
onLineageExpand,
|
|
|
|
selectedEntity,
|
2021-10-22 15:46:46 -07:00
|
|
|
hoveredEntity,
|
|
|
|
setHoveredEntity,
|
|
|
|
onDrag,
|
|
|
|
nodesToRender,
|
|
|
|
edgesToRender,
|
|
|
|
nodesByUrn,
|
2022-12-20 10:54:08 -05:00
|
|
|
setUpdatedLineages,
|
2021-04-03 11:13:25 -07:00
|
|
|
}: Props) {
|
2022-10-06 19:41:18 -04:00
|
|
|
const { highlightedEdges } = useContext(LineageExplorerContext);
|
2021-10-22 15:46:46 -07:00
|
|
|
const isLinkHighlighted = (link) =>
|
2022-10-06 19:41:18 -04:00
|
|
|
link.source.data.urn === hoveredEntity?.urn ||
|
|
|
|
link.target.data.urn === hoveredEntity?.urn ||
|
|
|
|
highlightedEdges.find(
|
|
|
|
(edge) =>
|
|
|
|
edge.sourceUrn === link.source.data.urn &&
|
|
|
|
edge.sourceField === link.sourceField &&
|
|
|
|
edge.targetUrn === link.target.data.urn &&
|
|
|
|
edge.targetField === link.targetField,
|
|
|
|
);
|
2021-04-03 11:13:25 -07:00
|
|
|
return (
|
2021-10-22 15:46:46 -07:00
|
|
|
<Group transform={transformToString(zoom.transformMatrix)} top={margin?.top} left={margin?.left}>
|
|
|
|
{[
|
|
|
|
// we want to render non-highlighted links first since svg does not support the
|
|
|
|
// concept of a z-index
|
|
|
|
...edgesToRender.filter((link) => !isLinkHighlighted(link)),
|
|
|
|
...edgesToRender.filter(isLinkHighlighted),
|
2022-11-18 12:28:30 -05:00
|
|
|
].map((link, idx) => {
|
2021-10-22 15:46:46 -07:00
|
|
|
const isHighlighted = isLinkHighlighted(link);
|
2022-11-18 12:28:30 -05:00
|
|
|
const key = `edge-${idx}-${link.source.data.urn}${link.sourceField && `-${link.sourceField}`}-${
|
|
|
|
link.target.data.urn
|
2022-11-23 18:14:21 -06:00
|
|
|
}${link.targetField && `-${link.targetField}`}-${link.target.direction}`;
|
2021-10-22 15:46:46 -07:00
|
|
|
|
2023-02-02 15:30:49 -08:00
|
|
|
return <LineageEntityEdge edge={link} key={key} isHighlighted={!!isHighlighted} />;
|
2021-04-03 11:13:25 -07:00
|
|
|
})}
|
2022-11-23 18:14:21 -06:00
|
|
|
{nodesToRender.map((node, index) => {
|
2021-04-03 11:13:25 -07:00
|
|
|
const isSelected = node.data.urn === selectedEntity?.urn;
|
|
|
|
const isHovered = node.data.urn === hoveredEntity?.urn;
|
2022-11-23 18:14:21 -06:00
|
|
|
const key = `node-${node.data.urn}-${node.direction}-${index}`;
|
2021-10-22 15:46:46 -07:00
|
|
|
|
2021-04-03 11:13:25 -07:00
|
|
|
return (
|
|
|
|
<LineageEntityNode
|
2022-11-23 18:14:21 -06:00
|
|
|
key={key}
|
2021-04-03 11:13:25 -07:00
|
|
|
node={node}
|
|
|
|
isSelected={isSelected}
|
|
|
|
isHovered={isHovered}
|
2022-10-06 19:41:18 -04:00
|
|
|
onHover={(select?: EntitySelectParams) => setHoveredEntity(select)}
|
2021-04-03 11:13:25 -07:00
|
|
|
onEntityClick={onEntityClick}
|
2021-04-23 00:18:39 -07:00
|
|
|
onEntityCenter={onEntityCenter}
|
2021-04-03 11:13:25 -07:00
|
|
|
onExpandClick={onLineageExpand}
|
2021-10-22 15:46:46 -07:00
|
|
|
isCenterNode={data.urn === node.data.urn}
|
2021-04-05 19:23:07 -07:00
|
|
|
nodesToRenderByUrn={nodesByUrn}
|
2021-10-22 15:46:46 -07:00
|
|
|
onDrag={onDrag}
|
2022-12-20 10:54:08 -05:00
|
|
|
setUpdatedLineages={setUpdatedLineages}
|
2021-04-03 11:13:25 -07:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</Group>
|
|
|
|
);
|
|
|
|
}
|