All files / src/pages/flowsheet-page/flowsheet/Canvas FlowsheetMiniMapNode.tsx

94.44% Statements 17/18
85.71% Branches 6/7
100% Functions 4/4
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115                                                      103x 103x     5447x   5126x             22698x             33294x                           5447x 33280x   5447x   5447x     23647x                 33059x 9647x                       3542x 18184x                                            
import type { ComponentType, MouseEvent } from "react";
import type { getMiniMapEdgeSpecs } from "./FlowsheetMiniMap.utils";
import {
  FlowsheetPreviewEdgeGlyph,
  FlowsheetPreviewNodeGlyph,
} from "./FlowsheetPreviewNodeGlyph";
import type {
  FlowsheetPreviewRenderGraph,
  FlowsheetPreviewRenderNode,
} from "./flowsheetPreviewRendering.ts";
 
type MiniMapNodeProps = {
  id: string;
  x: number;
  y: number;
  width: number;
  height: number;
  borderRadius: number;
  className: string;
  color?: string;
  shapeRendering: string;
  strokeColor?: string;
  strokeWidth?: number;
  selected: boolean;
  onClick?: (event: MouseEvent, id: string) => void;
};
 
const EDGE_LAYER_CLASS_NAME = "flowsheet-minimap-edge-layer";
const MINI_MAP_NODE_STROKE_WIDTH = 0.85;
 
function renderMiniMapEdges(edgeSpecs: ReturnType<typeof getMiniMapEdgeSpecs>) {
  if (!edgeSpecs.length) return null;
 
  return (
    <g
      className={EDGE_LAYER_CLASS_NAME}
      data-testid="flowsheet-minimap-edge-layer"
      pointerEvents="none"
    >
      {edgeSpecs.map((edge) => (
        <FlowsheetPreviewEdgeGlyph key={edge.id} edge={edge} />
      ))}
    </g>
  );
}
 
function renderMiniMapNodeGlyph(renderNode: FlowsheetPreviewRenderNode) {
  return (
    <FlowsheetPreviewNodeGlyph
      borderRadius={4}
      iconScale={0.55}
      layout={renderNode.layout}
      node={renderNode.node}
      opacity={renderNode.node.opacity}
      pointerEvents="none"
      strokeWidth={MINI_MAP_NODE_STROKE_WIDTH}
    />
  );
}
 
function renderMiniMapBackLayerNodes(renderGraph: FlowsheetPreviewRenderGraph) {
  const backLayerNodes = renderGraph.nodes.filter(
    (renderNode) => renderNode.layer === "back",
  );
  Iif (!backLayerNodes.length) return null;
 
  return (
    <>
      {backLayerNodes.map((node) => (
        <g key={node.node.id}>{renderMiniMapNodeGlyph(node)}</g>
      ))}
    </>
  );
}
 
function renderMiniMapNodeShape(
  renderNode: FlowsheetPreviewRenderNode | undefined,
) {
  if (!renderNode || renderNode.layer === "back") return null;
  return renderMiniMapNodeGlyph(renderNode);
}
 
export function createMiniMapNodeComponent({
  renderGraph,
  firstVisibleNodeId,
  edgeSpecs,
}: {
  renderGraph: FlowsheetPreviewRenderGraph;
  firstVisibleNodeId: string | undefined;
  edgeSpecs: ReturnType<typeof getMiniMapEdgeSpecs>;
}): ComponentType<MiniMapNodeProps> {
  const nodesById = new Map(
    renderGraph.nodes.map((renderNode) => [
      renderNode.node.id.toString(),
      renderNode,
    ]),
  );
 
  return function MiniMapSimulationObjectNodeComponent(
    props: MiniMapNodeProps,
  ) {
    return (
      <g pointerEvents="none">
        {props.id === firstVisibleNodeId ? (
          <>
            {renderMiniMapEdges(edgeSpecs)}
            {renderMiniMapBackLayerNodes(renderGraph)}
          </>
        ) : null}
        {renderMiniMapNodeShape(nodesById.get(props.id))}
      </g>
    );
  };
}