initial commit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import createGraph, { Graph } from "ngraph.graph";
|
||||
import createLayout from "ngraph.forcelayout";
|
||||
import { Node } from "../types";
|
||||
|
||||
const ITERATION_COUNT = 10;
|
||||
|
||||
export type Node2D = {
|
||||
id: Node['id'];
|
||||
position: { x: number, y: number };
|
||||
node: Node;
|
||||
}
|
||||
|
||||
export function build2dNodes(nodes: Node[], area: { width: number, height: number, padding: number }): Node2D[] {
|
||||
const graph = createGraph();
|
||||
for (const node of nodes) {
|
||||
graph.addNode(node.behaviour.id, { node });
|
||||
}
|
||||
for (const node of nodes) {
|
||||
for (const link of node.behaviour.getDisplayInfo().links)
|
||||
graph.addLink(node.behaviour.id, link.target);
|
||||
}
|
||||
return buildGraph2dNodes(graph, area);
|
||||
}
|
||||
|
||||
function buildGraph2dNodes(graph: Graph, area: { width: number, height: number, padding: number }): Node2D[] {
|
||||
const layout = createLayout(
|
||||
graph,
|
||||
{
|
||||
springLength: 300,
|
||||
// springTransform: (link, spring) => {
|
||||
// const from = graph.getNode(link.fromId).data.radius;
|
||||
// const to = graph.getNode(link.toId).data.radius;
|
||||
// spring.length = from + to + 10; // отступ 10px
|
||||
// },
|
||||
},
|
||||
);
|
||||
|
||||
function clampToBounds() {
|
||||
const minX = area.padding;
|
||||
const maxX = area.width - area.padding;
|
||||
const minY = area.padding;
|
||||
const maxY = area.height - area.padding;
|
||||
layout.forEachBody((body) => {
|
||||
if (body.pos.x < minX) { body.pos.x = minX; body.velocity.x = 0; }
|
||||
if (body.pos.x > maxX) { body.pos.x = maxX; body.velocity.x = 0; }
|
||||
if (body.pos.y < minY) { body.pos.y = minY; body.velocity.y = 0; }
|
||||
if (body.pos.y > maxY) { body.pos.y = maxY; body.velocity.y = 0; }
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0; i < ITERATION_COUNT; ++i) {
|
||||
layout.step();
|
||||
// clampToBounds();
|
||||
}
|
||||
|
||||
// const rect = layout.getGraphRect();
|
||||
// const W = area.width, H = 600, PADDING = 40;
|
||||
|
||||
// const scaleX = (area.width - area.padding * 2) / (rect.x2 - rect.x1);
|
||||
// const scaleY = (area.height - area.padding * 2) / (rect.y2 - rect.y1);
|
||||
// const scale = Math.min(scaleX, scaleY); // сохраняем пропорции
|
||||
|
||||
// function toCanvas(pos: { x: number; y: number }) {
|
||||
// return {
|
||||
// x: area.padding + (pos.x - rect.x1) * scale,
|
||||
// y: area.padding + (pos.y - rect.y1) * scale,
|
||||
// };
|
||||
// }
|
||||
|
||||
const nodes: Node2D[] = [];
|
||||
layout.forEachBody((body, nodeId) => {
|
||||
nodes.push({
|
||||
id: nodeId.toString(),
|
||||
position: { x: body.pos.x + area.width / 2, y: body.pos.y + area.height / 2 },
|
||||
node: graph.getNode(nodeId)?.data.node,
|
||||
});
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
Reference in New Issue
Block a user