MCPcopy Create free account
hub / github.com/OpenRaiser/PaperFlow / layoutGraph

Function layoutGraph

deployments/desktop/static/desktop.js:3640–3702  ·  view source on GitHub ↗
(nodes, edges)

Source from the content-addressed store, hash-verified

3638 }
3639
3640 function layoutGraph(nodes, edges) {
3641 const sourceNodes = uniqueGraphNodes((nodes || []).filter((node) => graphId(node).trim()));
3642 const sourceNodeIds = new Set(sourceNodes.map((node) => graphId(node)));
3643 const sourceEdges = (edges || [])
3644 .map(normalizeGraphEdge)
3645 .filter((edge) => sourceNodeIds.has(edge.src_id) && sourceNodeIds.has(edge.dst_id));
3646 const degree = graphDegreeMap(sourceNodes, sourceEdges);
3647 const groups = {
3648 topic: { x: 26, y: 31, nodes: [] },
3649 paper: { x: 42, y: 64, nodes: [] },
3650 method: { x: 70, y: 58, nodes: [] },
3651 frontier: { x: 74, y: 28, nodes: [] }
3652 };
3653 sourceNodes
3654 .slice()
3655 .sort((a, b) => (degree[graphId(b)] || 0) - (degree[graphId(a)] || 0))
3656 .forEach((node) => {
3657 const type = graphType(node);
3658 (groups[type] || groups.topic).nodes.push(node);
3659 });
3660
3661 const mapNodes = [];
3662 Object.entries(groups).forEach(([type, group]) => {
3663 const count = Math.max(1, group.nodes.length);
3664 group.nodes.forEach((node, index) => {
3665 const ring = Math.floor(index / 18);
3666 const slot = index % 18;
3667 const angle = (slot / Math.min(18, count)) * Math.PI * 2 + ring * 0.38;
3668 const radiusX = 7 + ring * 6 + (type === "paper" ? 3 : 0);
3669 const radiusY = 6 + ring * 4.5 + (type === "paper" ? 2 : 0);
3670 const id = graphId(node);
3671 const score = degree[id] || 0;
3672 mapNodes.push({
3673 ...node,
3674 id,
3675 node_id: id,
3676 type,
3677 x: clamp(group.x + Math.cos(angle) * radiusX, 5, 94),
3678 y: clamp(group.y + Math.sin(angle) * radiusY, 8, 91),
3679 size: score >= 2.5 ? "large" : score >= 1.0 ? "medium" : "small",
3680 real_node_id: id
3681 });
3682 });
3683 });
3684 const map = {
3685 nodes: mapNodes,
3686 edges: sourceEdges,
3687 sourceNodes,
3688 sourceEdges,
3689 byId: Object.fromEntries(mapNodes.map((node) => [node.id, node]))
3690 };
3691 state.wikiMap = map;
3692 const focusId = state.currentWikiNodeId && map.byId[state.currentWikiNodeId]
3693 ? state.currentWikiNodeId
3694 : pickWikiFocusNodeId();
3695 return {
3696 nodes: map.nodes.map((node) => ({ ...node, x: node.x, y: node.y, type: node.type, size: node.size })),
3697 edges: map.edges,

Callers 1

renderWikiGraphFunction · 0.85

Calls 6

uniqueGraphNodesFunction · 0.85
graphIdFunction · 0.85
graphDegreeMapFunction · 0.85
graphTypeFunction · 0.85
pickWikiFocusNodeIdFunction · 0.85
clampFunction · 0.70

Tested by

no test coverage detected