Need to achieve this diagram using dynamic ports layout


Is it possible to achieve the above diagram using dynamic port layout.
This is a representation of ONTs systems connected in an organization.

Here I have given a all-possible connection between nodes and I don’t have idea about node data array.

Did you want to create something like this?


(Sorry, I did not try to reproduce the same graph that you show in your sketch.)

Here’s the complete code for this. The textarea underneath the Div (Diagram) just shows the contents of the Diagram.model in JSON format.

Note that I did explicitly have one Link go directly between the Nodes rather than be routed orthogonally avoiding nodes.

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2024 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
  <textarea id="mySavedModel" style="width:100%;height:250px"></textarea>

  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
const $ = go.GraphObject.make;

const myDiagram =
  new go.Diagram("myDiagramDiv",
    {
      layout: new go.ForceDirectedLayout({ maxIterations: 400 }),
      "undoManager.isEnabled": true,
      "ModelChanged": e => {     // just for demonstration purposes,
        if (e.isTransactionFinished) {  // show the model data in the page's TextArea
          document.getElementById("mySavedModel").textContent = e.model.toJson();
        }
      }
    });

myDiagram.nodeTemplate =
  $(go.Node, "Auto",
    { width: 120, height: 60, locationSpot: go.Spot.Center },
    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
    $(go.Shape, "RoundedRectangle",
      {
        fill: "white", stroke: "gray", strokeWidth: 3,
        portId: "",
        fromSpot: go.Spot.AllSides, toSpot: go.Spot.AllSides
      }),
    $(go.TextBlock,
      new go.Binding("text"))
  );

myDiagram.linkTemplate =
  $(go.Link,
    { routing: go.Link.AvoidsNodes, corner: 10 },
    new go.Binding("routing", "straight", s => s ? go.Link.Normal : go.Link.AvoidsNodes),
    $(go.Shape, { stroke: "orange", strokeWidth: 3 })
  );

myDiagram.model = new go.GraphLinksModel(
[
  { key: 1, text: "Alpha" },
  { key: 2, text: "Beta" },
  { key: 3, text: "Gamma" },
  { key: 4, text: "Delta" },
  { key: 5, text: "Epsilon" }
],
[
  { from: 1, to: 2 },
  { from: 1, to: 3 },
  { from: 2, to: 5, straight: true },
  { from: 3, to: 4 },
  { from: 4, to: 1 },
  { from: 4, to: 5 }
]);
  </script>
</body>
</html>

Thanks for quick response @walter
How to avoid the links that are overlapping?
And my network will have upto 1k nodes , they should be arranged like this without intersection or overlapping of links and nodes.
If possible, could you please help me on this?

Regarding link segments that overlap: there is no good solution at this time, but you could use the code referenced in Extending Dynamic Ports Link Routing Overlapping Issue

In version 3.0 we will provide similar functionality but better. However we’re not quite at the stage for a beta release.

Are you saying that your graph will be planar? Otherwise there will have to be intersections between links. Or is it OK for links to cross each other?

Can you characterize the nature of the graph that you want to display, other than having 1000 nodes? How many links? If the graph will not be planar, what relationships will there be?

2 posts were split to a new topic: Different layouts in one diagram

Recording 2024-01-16 150934
I have implemented a layout (ForceDirectedLayout) as you said earlier. Each time while refreshing the diagram looks different. Can’t it be same for every time? And I want the diagram to spread horizontally but not vertically.

Set ForceDirectedLayout | GoJS API to null or your own custom random number generator.

You might want to override ForceDirectedLayout | GoJS API in order to discourage vertexes from going beyond a particular range of Y values.

Thanks for the reply @walter I am struggling in how to override the electricalFieldY method. Could you please help?

Here’s a demo: Viewport-constrained ForceDirectedLayout
But instead of trying to fit into the viewport bounds, you’ll want to limit it between two horizontal lines.

image
I need ports for each and every links connected dynamically. Can you please help on this #walter

You should not need separate ports on each node. But perhaps I misunderstand your requirements. Why do you think you need a different port for each connected link when you can assign Link.fromSpot and Link.toSpot on any link?

Hi @walter Is there any way to automatically/dynamically place ports (in the left or right or top or bottom) on the nodes based on the connecting links? But Link should not come over the node to connect the other node’s port.

If you don’t use separate small ports you will not have that problem.
So I suggest that you don’t try to specify on which side a links connects.

Try to describe your requirements without specifying implementation technique.

I have 10 systems (with different # of ports).
nda = [
{key : ‘system1’, portArray : [{portId : 0}, {portId : 1}]},
{key : ‘system2’, portArray : [{portId : 0}, {portId : 1}, {portId : 2}]},
{key : ‘system3’, portArray : [{portId : 0}, {portId : 1}]},

{key : ‘system4’, portArray : [{portId : 0}, {portId : 1}, {portId : 2}, {portId : 3}]},
{key : ‘system5’, portArray : [{portId : 0}, {portId : 1}]},

{key : ‘system6’, portArray : [{portId : 0}, {portId : 1}, {portId : 2}, {portId : 3}, {portId : 4}]},
{key : ‘system7’, portArray : [{portId : 0}, {portId : 1}]},
{key : ‘system8’, portArray : [{portId : 0}, {portId : 1}]},
{key : ‘system9’, portArray : [{portId : 0}, {portId : 1}, {portId : 2}, {portId : 3}]},
{key : ‘system10’, portArray : [{portId : 0}, {portId : 1}]}
];
lda = [{“from”:“system2”,“fromPort”:0,“to”:“system8”,“toPort”:0},{“from”:“system2”,“fromPort”:2,“to”:“system9”,“toPort”:2},{“from”:“system3”,“fromPort”:0,“to”:“system9”,“toPort”:1},{“from”:“system3”,“fromPort”:1,“to”:“system6”,“toPort”:1},{“from”:“system4”,“fromPort”:2,“to”:“system6”,“toPort”:0},{“from”:“system5”,“fromPort”:0,“to”:“system10”,“toPort”:1},{“from”:“system5”,“fromPort”:1,“to”:“system9”,“toPort”:3},{“from”:“system6”,“fromPort”:0,“to”:“system4”,“toPort”:0},{“from”:“system6”,“fromPort”:2,“to”:“system1”,“toPort”:0},{“from”:“system6”,“fromPort”:3,“to”:“system10”,“toPort”:1},{“from”:“system6”,“fromPort”:4,“to”:“system4”,“toPort”:0},{“from”:“system7”,“fromPort”:0,“to”:“system2”,“toPort”:1},{“from”:“system7”,“fromPort”:1,“to”:“system4”,“toPort”:1},{“from”:“system8”,“fromPort”:0,“to”:“system1”,“toPort”:1},{“from”:“system9”,“fromPort”:0,“to”:“system8”,“toPort”:0},{“from”:“system9”,“fromPort”:2,“to”:“system1”,“toPort”:0},{“from”:“system10”,“fromPort”:1,“to”:“system9”,“toPort”:2}];

I want all these nodes and ports has to be set in a layout looking like below (Just an example). Nodes and links should not collide.
image

image
It should look like this with ports.

Please help on this @walter

I still would like to understand why you believe you need “ports”.

Is the requirement that two or more links that connect with a node using the same port connect at the same point on the side of the node?

But you don’t care where the port is on its node?

In addition you don’t want links crossing over nodes.

Is the requirement that two or more links that connect with a node using the same port connect at the same point on the side of the node?

But you don’t care where the port is on its node?
In addition you don’t want links crossing over nodes.

EXACTLY!!

OK, that is an unusual requirement but should be achievable. I can work on it later today.

By the way, your bigger screenshot with the orange links does not convey your requirement because there are no cases where multiple links connect with the same node at the same point on that node.

Thanks.

sorry for that @walter

@walter Also nodes can have more number of ports. Based on the # of ports, the nodes size should increase or else please suggest me a good option in that case

Surely there’s some content that you want to show within the node, yes?
Wouldn’t you want the node size to be influenced by how big the content is?
If not, that’s OK too.