function GraphVisualization()

in studio/src/components/graph-visualization.tsx [104:269]


function GraphVisualization({
  subgraphMetrics,
  federatedGraphMetrics,
  supportsFederation,
}: {
  subgraphMetrics?: SubgraphMetrics[];
  federatedGraphMetrics?: FederatedGraphMetrics;
  supportsFederation: boolean;
}) {
  const graphData = useContext(GraphContext);
  const reactFlowInstance = useReactFlow();
  const nodesInitialized = useNodesInitialized();
  const dr = useDateRangeQueryState();

  const [nodes, setNodes] = useState<Node[]>([]);
  const [edges, setEdges] = useState<Edge[]>([]);

  const [showAll, setShowAll] = useState(false);
  const [topCategory, setTopCategory] = useState("latency");

  const subgraphs = useMemo(() => {
    let tempSubgraphs = [...(graphData?.subgraphs ?? [])];

    tempSubgraphs.sort((a, b) => {
      const metricA = subgraphMetrics?.find((x) => x.subgraphID === a.id);
      const metricB = subgraphMetrics?.find((x) => x.subgraphID === b.id);

      if (!metricA || !metricB) {
        return 0;
      }

      if (topCategory === "latency") {
        return metricB.latency - metricA.latency;
      }
      if (topCategory === "errorRate") {
        return metricB.errorRate - metricA.errorRate;
      }

      return metricB.requestRate - metricA.requestRate;
    });

    if (!showAll) {
      tempSubgraphs = tempSubgraphs.slice(0, 5);
    }

    return tempSubgraphs;
  }, [showAll, topCategory, graphData?.subgraphs, subgraphMetrics]);

  useEffect(() => {
    if (!graphData?.graph) return;

    const buildGraphs = (subgraphs: Subgraph[]): Graph[] => {
      const rootName = supportsFederation ? graphData.graph?.name : "router";

      const graphs: Graph[] = [
        {
          id: `root-${rootName}`,
          kind: "graph",
          name: rootName!,
          parentId: "",
          errorRate: federatedGraphMetrics?.errorRate,
          requestRate: federatedGraphMetrics?.requestRate,
        },
      ];
      for (const subgraph of subgraphs) {
        graphs.push({
          id: `root-${graphData.graph?.name}-${subgraph.name}}`,
          subgraphId: subgraph.id,
          kind: "subgraph",
          name: subgraph.name,
          parentId: graphs[0].id,
        });
      }
      return graphs;
    };

    let graphs = buildGraphs(subgraphs);

    const buildNodes = (spans: Graph[]): Node[] => {
      return spans.map((span, index) => {
        if (span.kind === "graph") {
          return {
            id: span.id,
            type: "span",
            data: {
              label: span.name,
              kind: span.kind,
              parentId: span.parentId,
              errorRate: federatedGraphMetrics?.errorRate,
              requestRate: federatedGraphMetrics?.requestRate,
            },
            connectable: false,
            deletable: false,
            position: {
              x: 0,
              y: 0,
            },
          };
        }
        const sm = subgraphMetrics?.find(
          (x) => x.subgraphID === span.subgraphId,
        );
        return {
          id: span.id,
          type: "span",
          data: {
            label: span.name,
            kind: span.kind,
            parentId: span.parentId,
            errorRate: sm?.errorRate,
            requestRate: sm?.requestRate,
          },
          connectable: false,
          deletable: false,
          position: {
            x: 0,
            y: 0,
          },
        };
      });
    };

    const buildEdges = (spans: Graph[]): Edge[] => {
      return spans
        .filter((s) => !!s.parentId)
        .map((span, index) => {
          const sm = subgraphMetrics?.find(
            (x) => x.subgraphID === span.subgraphId,
          );
          return {
            id: span.id,
            source: span.parentId,
            animated: true,
            target: span.id,
            type: "metricsEdge",
            data: {
              latency: sm?.latency,
            },
          };
        });
    };

    if (!graphs.length) {
      return;
    }

    const n = buildNodes(graphs);
    const e = buildEdges(graphs);

    // Create a new directed graph per graph
    // otherwise a single graph will contain all nodes and edges from all graphs
    // this will cause the layout to be incorrect when not all nodes and edges have unique ids
    const dagreGraph = new dagre.graphlib.Graph();
    dagreGraph.setDefaultEdgeLabel(function () {
      return { minlen: 5, weight: 1 };
    });

    const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(
      dagreGraph,
      n,
      e,
    );

    setNodes(layoutedNodes);
    setEdges(layoutedEdges);
  }, [