Coder Social home page Coder Social logo

inet-henge's Introduction

inet-henge.js

inet-henge.js generates d3.js based Auto Layout Network Diagram from JSON data.
inet-henge helps you draw it by calculating coordinates automatically, placing nodes and links in SVG format.

Each object is draggable and zoomable.

stone-henge

All you have to do are:

  1. Define nodes identified by name
  2. Define links by specifying both end nodes
  3. Show in a browser. That's it.

JSON example:

{
  "nodes": [
    { "name": "A" },
    { "name": "B" }
  ],

  "links": [
    { "source": "A", "target": "B" }
  ]
}

Getting Started

npm install inet-henge

# or

git clone https://github.com/codeout/inet-henge.git

Then host the root directory in your favorite web server.

ruby -run -e httpd . -p 8000

Now you can see http://localhost:8000/example.

python -m SimpleHTTPServer  # python2
python -m http.server       # python3

or

php -S 127.0.0.1:8000

are also available to start a web server.

Demo

Usage

In example here, load related assets at first:

  • d3.js v3
  • cola.js
    • ⚠️ It doesn't support d3.js v4 ⚠️
  • inet-henge.js
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />

    <!-- You can customize a style of network diagram by CSS -->
    <link href="style.css" rel="stylesheet" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
    <script src="../vendor/cola.min.js"></script>
    <script src="../inet-henge.js"></script>
  </head>

define a blank container:

<body>
  <div id="diagram"></div>
</body>

and render your network diagram:

  <script>
   new Diagram("#diagram", "shownet.json").init("interface");
  </script>
</html>

Object is also acceptable:

  <script>
    const data = {
      "nodes": [{ "name": "A" }, { "name": "B" }],
      "links": [{ "source": "A", "target": "B" }]
    };
   new Diagram("#diagram", data).init("interface");
  </script>
</html>

inet-henge.js renders your network diagram as SVG within <div id="diagram"></div>. In the example above the diagram also displays metadata labelled "interface" which defined in JSON data.

Shownet2016 example

JSON Data

Minimal json looks like:

{
  "nodes": [
    { "name": "A" },
    { "name": "B" }
  ],

  "links": [
    { "source": "A", "target": "B" }
  ]
}

You can specify node icon by URL:

  "nodes": [
    { "name": "dceast-ne40e", "icon": "./images/router.png" }
  ]

Metadata to display on network diagrams:

new Diagram("#diagram", "index.json").init("interface");
  "links": [
    {
      "source": "noc-asr9904", "target": "noc-ax8616r",
      "meta": {
        "interface": { "source": "0-0-0-2", "target": "1-1" }
      }
    }
  ]

☝️ This will render metadata on both ends of links.

Node Group

Nodes get rendered in groups when you specify which node belongs to which group by regular expression.

When the first three characters describe POP name, you can group nodes by doing this:

const diagram = new Diagram("#diagram", "data.json", { pop: /^.{3}/ });

Labels

When init() API is called with arguments, inet-henge finds corresponding metadata and show them as labels.

To place a loopback address on nodes:

new Diagram("#diagram", "index.json").init("loopback");
{
  "nodes": [
    { "name": "Node 1", "meta": { "loopback": "10.0.0.1" } },
    ...
  ],
  ...
}

Label on node

To place link and interface names:

new Diagram("#diagram", "index.json").init("bandwidth", "intf-name");
{
  ...
  "links": [
    {
      "source": "Node 1", "target": "Node 2",
      "meta": {
        "bandwidth": "10G",
        "intf-name": { "source": "interface A", "target": "interface B" }
      }
    },
    ...
  ]

Label on link

Node Size

You can change node width and height:

const diagram = new Diagram("#diagram", "data.json", { nodeWidth: 120, nodeHeight: 30 });

Node Size

Width 60 and heigh 40 (px) by default.

Link Width

You can use linkWidth() API to customize link widths. The argument should be a function which calculates metadata and returns value for stroke-width of SVG.

const diagram = new Diagram("#diagram", "index.json");
diagram.linkWidth(function (link) {
  if (!link)
    return 1;  // px
  else if (link.bandwidth === "100G")
    return 10; // px
  else if (link.bandwidth === "10G")
    return 3;  // px
  else if (link.bandwidth === "1G")
    return 1;  // px
});
diagram.init("bandwidth");
  "links": [
    { "source": "Node 1", "target": "Node 2", "meta": { "bandwidth": "1G" }},
    { "source": "Node 1", "target": "Node 3", "meta": { "bandwidth": "10G" }},
    { "source": "Node 2", "target": "Node 3", "meta": { "bandwidth": "100G" }}
  ]

Link width

⚠️ Make sure no stylesheet overrides customized link widths. ⚠️

Group Size

You can specify padding to increase the size of groups (default: 1):

const diagram = new Diagram("#diagram", "data.json", { groupPadding: 30 });

Group Size

💡 Position calculation sometimes gets stuck when increasing groupPadding. initialTicks may help in such cases.

Ticks

You can specify the number of steps (called as ticks) to calculate with d3-force layout. Bigger ticks typically converge on a better layout, but it will take much longer until settlement. The default value is 1000.

const diagram = new Diagram("#diagram", "data.json", { ticks: 3000 });

For large scale network diagrams, you can also specify the number of initial unconstrained ticks.

const diagram = new Diagram("#diagram", "data.json", { initialTicks: 100, ticks: 100 });

inet-henge calculates the layout in two iteration phases:

  1. Initial iteration with no constraints. ( default: 0 tick )
  2. The main iteration with constraints that apply groups as bounding boxes, prevent nodes and groups from overlapping with each other, and so on. ( default: 1000 ticks )

If you increase initialTicks, inet-henge calculates faster in exchange for network diagram precision so that you can decrease ticks which is the number of main iteration steps.

20 ~ 100 initialTicks and 70 ~ 100 ticks should be good start for 800 nodes with 950 links for example. It takes 20 ~ 30 seconds to render in the benchmark environment.

Position Cache

inet-henge caches a calculated position of nodes, groups, and links for the next rendering. If you load the same JSON data, the cache will be used as a position hint. You can disable this behavior with positionCache option.

const diagram = new Diagram("#diagram", "data.json", { positionCache: false });

SVG viewport size

You can change svg's viewport size:

const diagram = new Diagram("#diagram", "data.json", { width: 1200, height: 600 });

This will generate:

<svg width="1200" height="600">

Style

inet-henge generates an SVG image, so you can customize the style by using CSS.

Display bundles

You can display multiple links between nodes by setting bundle: true in the constructor like:

<script>
  const diagram = new Diagram("#diagram", "index.json", { pop: /^([^\s-]+)-/, bundle: true });
  diagram.init("loopback", "interface");
</script>

Bundle example

Nodes are connected to each other with a single link by default.

Save positions after dragging nodes

You can save positions of all nodes in browser even after dragging them by setting positionCache: "fixed" in the constructor like:

<script>
  const diagram = new Diagram("#diagram", "index.json", { pop: /^([^\s-]+)-/, positionCache: "fixed" });
  diagram.init("loopback", "interface");
</script>

Position hinting

You can provide the coordinates of nodes as position hints to place them where you want. inet-henge calculates the layout by considering them. It always refers to position cache over hint when there is a cache.

💡 They are "hints". Nodes won't be strictly placed there.

const diagram = new Diagram("#diagram", "index.json", {
  pop: /^([^\s-]+)-/,
  bundle: true,
  positionHint: {
    nodeCallback: (node) => {
      const [_, pop] = node.name.match(/^([^\s-]+)-/);

      // specify the position of nodes in POP01
      if (pop === "POP01") {
        return { x: 600, y: 330 };
      }

      // unspecified
      return null;
    },
  },
});

diagram.init("loopback", "interface", "description", "type");
  • Use nodeCallback option to specify per node.
    • The Node object is passed as an argument.
    • Return value should be an object like {x: 600, y: 330}.
    • If the callback returns null, this means that the node position is unspecified.

Position hinting

💡 How position hinting works

The position hints are initial positions technically.

  1. inet-henge places nodes according to the hints.
    • When no hint is specified, the node will be placed in the center of the diagram.
  2. Then, it starts the ticks calculation.

Metadata tooltip

You can display node metadata in the tooltip, instead of always showing as node text, by setting tooltip: "click" in the constructor like:

<script>
  const diagram = new Diagram("#diagram", "index.json", { pop: /^([^\s-]+)-/, tooltip: "click" });
  diagram.init("description", "type");
</script>

In the example above, description and type will be displayed.

  "nodes": [
    { "name": "POP01-bb01", "meta": {"description": "This is a router", "type": "Backbone"}, "icon": "./images/router.png" },
    { "name": "POP01-bb02", "meta": {"description": "This is a router", "type": "Backbone"}, "icon": "./images/router.png" },
    { "name": "POP01-ag01", "meta": {"description": "This is a router", "type": "Aggregation"}, "icon": "./images/switch.png" },
    { "name": "POP01-ag02", "meta": {"description": "This is a router", "type": "Aggregation"}, "icon": "./images/switch.png" },

Metadata tooltip

💡 tooltip: "hover" is also available.

Hyperlink in tooltop

You can show <a href="...">...</a> in node metadata tooltips.

<script>
  const diagram = new Diagram("#diagram", "index.json", {
    pop: /^([^\s-]+)-/,
    bundle: true,
    tooltip: "click",
    href: (t, type) => {
      switch (type) {
        case "node":
          // {
          //   "name": "POP01-bb01",
          //   "meta": { "description": "This is a router", "type": "Backbone" },
          //   "icon": "./images/router.png"
          // }
          return `https://example.com/node/${tooltip.node.meta?.type}/${tooltip.node.name}`;
        case "link":
          // {
          //   "source": "POP03-bb01",
          //   "target": "POP03-bb02",
          //   "meta": { "interface": { "source": "ge-0/0/0", "target": "Te0/0/0/0" } }
          // }
          return `https://example.com/link/${tooltip.link.source.name}-${tooltip.link.target.name}`;
      }
    }
  });
  diagram.init("interface", "description", "type");
</script>

This example above will generate <a href="https://example.com/node/Backbone/POP01-bb02">...</a>.

💡 Use tooltip: "click" to make tooltips sticky.

Initial Position and Scale

You can specify initial position and scale of diagram.

<script>
  const diagram = new Diagram("#diagram", "index.json");
  diagram.init();

  // move 100px in both x and y, and show in 1/2 scale
  diagram.attr("transform", "translate(100, 100) scale(0.5)");
</script>

Experimental Features

⚠️ Those features may work, but still under development. The behavior might be changed ⚠️

Position constraints

You can apply x-axis or y-axis based position constraints to nodes.

Here is an example.

Position constraints

<script>
  const diagram = new Diagram("#diagram", "clos.json", {
    positionHint: {
      nodeCallback: (node) => {
        switch (true) {
          // spines, leaves, and servers from the top
          case /^spine/.test(node.name):
            return { x: 300, y: 100 };
          case /^leaf/.test(node.name):
            return { x: 300, y: 200 };
          case /^server/.test(node.name):
            return { x: 300, y: 300 };
        }
      }
    },
    positionConstraints: [{
      axis: "y",
      nodesCallback: (nodes) => [
        // all spines should be in line in y-axis. leaves and servers as well.
        nodes.filter((n) => /^spine/.test(n.name)),
        nodes.filter((n) => /^leaf/.test(n.name)),
        nodes.filter((n) => /^server/.test(n.name)),
      ]
    }]
  });
  diagram.init();
</script>
  • Use nodesCallback option to create node groups.
    • The Node object is passed as an argument.
    • Individual constraints will be applied to each group.

You may want to define Position hinting besides constraints. Please note that hint is just a hint and nodes won't be strictly placed there, while constraint is always satisfied.

Internal groups

You can display node type based groups in POP-based Node group by group definition in each node.

  "nodes": [
    { "name": "POP01-bb01", "group": "core", "icon": "./images/router.png" },
    { "name": "POP01-bb02", "group": "core", "icon": "./images/router.png" },
    ...

Internal group

Bundle Mark

You can show a "tie" over bundled links by bundle: definition in each link.

  "links": [
    { "source": "POP01-bb01", "target": "POP01-bb02", "bundle": "lag 1" },
    { "source": "POP01-bb01", "target": "POP01-bb02", "bundle": "lag 1" },
    { "source": "POP01-bb01", "target": "POP01-bb02"}
  ]

Bundle example

  • Define bundle name as bundle: to specify which link belongs to the bundle ( integer or string value )
  • Set bundle: true when initializing Diagram. See Display bundles section for details.
  • inet-henge draws a "tie" when there are multiple links in bundle among the same node pair. It doesn't draw the mark between different node pairs, even when bundle names are the same.

⚠️ Multi-chassis bundling is not supported.

Plugins

Name Note
Removable Node Plugin Hide and show nodes by key inputs
Arrows Link Plugin Make links bidirectional arrows

Contributing

Please report issues or enhancement requests to GitHub issues. For questions or feedbacks write to my twitter @codeout.

Or send a pull request to fix.

Copyright and License

Copyright (c) 2016-2024 Shintaro Kojima. Code released under the MIT license.

inet-henge's People

Contributors

codeout avatar dependabot[bot] avatar tetsuro-nakamura avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

inet-henge's Issues

Possible solution for hierarchical design

Hi, after last update I would like to point out one possible solution for hierarchical design but I would need your help.
I found really good tutorial here:
https://www.alyne.com/en/blog/tech-talk/using-webcola-and-d3-js-to-create-hierarchical-layout/

Here are the steps I took:
1.Changed diagram.ts
a) import * as _ from 'lodash';
b)

initCola(): any { // eslint-disable-line @typescript-eslint/no-explicit-any return cola.d3adaptor() .avoidOverlaps(true) .handleDisconnected(false) .symmetricDiffLinkLengths(100) .linkDistance(100) .size([this.options.width, this.options.height]); }

c) inside render function I added this
`const levelGroups = _.groupBy(nodes, "level");
console.log(levelGroups)
for (const level of Object.keys(levelGroups)) {
const nodeGroup = levelGroups[level];
const constraint = {
type: "alignment",
axis: "y",
offsets: [],
};
let prevNodeId = "none";
for (const node of nodeGroup) {
constraint.offsets.push({
node: _.findIndex(nodes, (d) => d.name === node.name),
offset: 0,
});

              if (prevNodeId !== "none") {
                console.log(_.findIndex(nodes, (d) => d.name === prevNodeId));
                console.log(_.findIndex(nodes, (d) => d.name === node.name));
                
                constraints.push({
                  axis: "x",
                  left: _.findIndex(nodes, (d) => d.name === prevNodeId),
                  right:_.findIndex(nodes, (d) => d.name === node.name),
                  gap: 50,
                });
              }
      
              prevNodeId = node.name;
              console.log(prevNodeId);
            }
      
            constraints.push(constraint);
        }
        
this.cola.nodes(nodes)
            .links(links)
            **.constraints(constraints)**
            .groups(groups);
        this.setDistance(this.cola);`

d) in node.ts I added level property
in NodeDataType - level: number,
in Node Class - public level: number;
in constructor - this.level = data.level;

e) in package.json in dependencies I added
"@types/lodash": "^4.14.168",
"lodash": "^4.17.20",

JSON here - you can see I added level property:
{ "nodes": [ { "level":1, "name": "testPERMANENT-10.0.1.1", "meta": { "tenant-ip": "10.0.1.1" }, "icon": "/static/images/router.png" }, { "level":1, "name": "testPERMANENT-10.0.1.2", "meta": { "tenant-ip": "10.0.1.2" }, "icon": "/static/images/router.png" }, { "level":2, "name": "INTERNET", "icon": "/static/images/router.png" }, { "level":3, "name": "AZ1-testpermanent-123-muc-vpn1", "meta": { "name": "vpn1" }, "icon": "/static/images/router.png" }, { "level":3, "name": "AZ2-testpermanent-123-muc-vpn2", "meta": { "name": "vpn2" }, "icon": "/static/images/router.png" }, { "level":4, "name": "AZ1-testpermanent-muc-rs1", "meta": { "name": "rs1" }, "icon": "/static/images/router.png" }, { "level":4, "name": "AZ1-testpermanent-muc-rs2", "meta": { "name": "rs2" }, "icon": "/static/images/router.png" }, { "level":4, "name": "AZ2-testpermanent-muc-rs3", "meta": { "name": "rs3" }, "icon": "/static/images/router.png" }, { "level":4, "name": "AZ2-testpermanent-muc-rs4", "meta": { "name": "rs4" }, "icon": "/static/images/router.png" }, { "level":5, "name": "10.0.0.0/24" }, { "level":5, "name": "10.0.1.0/24" }, { "level":6, "name": "POD1-FCIPOCLEAF101", "meta": { "name": "FCIPOCLEAF101" }, "icon": "/static/images/router.png" }, { "level":7, "name": "POD1-FCIPOCLEAF102", "meta": { "name": "FCIPOCLEAF102" }, "icon": "/static/images/router.png" }, { "level":6, "name": "POD2-FCIPOCLEAF202", "meta": { "name": "FCIPOCLEAF202" }, "icon": "/static/images/router.png" }, { "level":7, "name": "POD2-FCIPOCLEAF201", "meta": { "name": "FCIPOCLEAF201" }, "icon": "/static/images/router.png" } ], "links": [ { "source": "10.0.0.0/24", "target": "AZ1-testpermanent-muc-rs1" }, { "source": "10.0.0.0/24", "target": "AZ1-testpermanent-muc-rs2" }, { "source": "10.0.0.0/24", "target": "POD1-FCIPOCLEAF102" }, { "source": "10.0.0.0/24", "target": "POD1-FCIPOCLEAF101" }, { "source": "10.0.0.0/24", "target": "POD2-FCIPOCLEAF201" }, { "source": "10.0.0.0/24", "target": "POD2-FCIPOCLEAF202" }, { "source": "10.0.1.0/24", "target": "AZ2-testpermanent-muc-rs3" }, { "source": "10.0.1.0/24", "target": "AZ2-testpermanent-muc-rs4" }, { "source": "10.0.1.0/24", "target": "POD1-FCIPOCLEAF102" }, { "source": "10.0.1.0/24", "target": "POD1-FCIPOCLEAF101" }, { "source": "10.0.1.0/24", "target": "POD2-FCIPOCLEAF201" }, { "source": "10.0.1.0/24", "target": "POD2-FCIPOCLEAF202" }, { "source": "INTERNET", "target": "AZ1-testpermanent-123-muc-vpn1" }, { "source": "INTERNET", "target": "AZ2-testpermanent-123-muc-vpn2" }, { "source": "INTERNET", "target": "testPERMANENT-10.0.1.1" }, { "source": "INTERNET", "target": "testPERMANENT-10.0.1.2" }, { "source": "10.0.0.0/24", "target": "AZ1-testpermanent-123-muc-vpn1" }, { "source": "10.0.1.0/24", "target": "AZ2-testpermanent-123-muc-vpn2" } ] }

I think it works but not 100% because in the link I provided the generated graph is topdown but for example here LEVEL 1 is displayed at the bottom. And for example if I have groups, one node is displayed at the same level even though its one level lower. So I think it has to do something with groups and constraints.

JSON to image below:
vpns are level 1
internet is level 2
etc. but if you look at LEAFS which are aligned with RS this should not be like that because they have different levels but grouping is a problem maybe

image

you can see without groups it works better but still not great
image

Changing Behavior of inline layout

  1. I have three groups (might be more in future). If i don't connect nodes in-between the groups, they are just placed below one another.

Screen Shot 2020-12-16 at 17 36 30

Is there a way to place them side-by-side without adding extra connections?
Or maybe place the groups in a horizontal layout?

  1. Also in each group, lines are overlapping one another.

Screen Shot 2020-12-16 at 17 51 29

But i was hoping to have a layout something similar to the following image without adding extra connections.
Screen Shot 2020-12-16 at 17 52 50

Store a fixed position in the .json file?

Hi,

I was wondering if there is a way to store fixed position inside the .json file?

If I understand correctly the positionCache option will store the position in the browser cache.
I would like to store a fixed position in the json file so all the users will see the same initial diagram.

Thanks a lot for your help.

Adding onClick listeners to nodes

Hi, thank you for providing us with such an amazing work.
I was just wondering if the graph can be made a bit lively, for example, adding onClick listeners to nodes which changes the assigned icon if available or assigns a new icon, or maybe clicking two nodes will change the link width or color.
If i want to do something like this, where can i start, like editing the js?
Any hints will be appreciated as i am relatively new to coding in js.

'Star' Layout in a Pop

iNet-Henge is great. I like it...
But I have an issue when is 'Pop' related devices.
So I have added a switch node and a load of PC nodes.
I then link each of the PC's to the switch.

If I don't 'Pop' them they display radially, in a star around my switch.
If i do 'Pop' them they display in 1 column.
How can I fix this? Is it me?

Thanks
Steve

Ability to insert hyperlinks into tooltips

Hello,

Thanks for the project, it is really coming handy in our work.

I was wondering, is it possible to inject a hyperlink into a tooltip? Or any other HTML code, for that matter.
As I see, the content inside a tooltip is being composed dynamically and packed into objects.

Positioning the map

I conduct a search for nodes.
Got the coordinates of the node
How to position the map so that the node is in the center of the screen

Tooltips are not being displayed (loopbacks are missing too)

Hi,
I'm having an issue where description and type are not displayed as per your documentation. I have the following:

<script>
    const data = {{ data.network_topology | safe }};
    const distance = function (force) {
        force.jaccardLinkLengths(70, 1.0);
    };
    const diagram = new Diagram(
        "#diagram",
        data,
        {
            nodeWidth: 120,
            nodeHeight: 30,
            positionCache: false,
            initialTicks: 10,
            ticks: 1500,
            tooltip: "click",
            width: 1200,
            height: 600,
            distance: distance
        }
    );
    diagram.linkWidth(function (link) {
        if (!link)
            return 1;
        else if (link.bandwidth === "100G")
            return 10;
        else if (link.bandwidth === "10G")
            return 3;
        else if (link.bandwidth === "1G")
            return 2;
    });
    diagram.init(
        "description",
        "type",
        "loopback",
        "bandwidth",
        "interface",
        "intf-name"
    );
    // diagram.svg.attr("transform", "translate(100, 100) scale(1.5)");
</script>

Nodes are setup identically with an exception of naming convention:

{
        'name': 'brlb-t4core-1a',
        'group': 'CORE',
        'meta': {
            'loopback': '172.19.10.27',
            'type': 'Core',
            'description': 'Core - Aggregation Network'
        }
    }

Zoomed View

Hi, I have a 3 node topology and on the load everything appears to be zoomed out. Is there a way to load the topology zoomed in?

POP optional variable

Hi,

Is it possible to add "meta" with "pop" option instead of using POP parsing from node name? Currently when adding WAN circuits with "Clouds" and ISP names it makes it look very messy.

Thank you.

BUG - Position Cache

When you change the position of the node, the cache is not updated, there are data that were cached when initializing

Request for some changes to label and links so that the visibility of the dense graphs can be improved

@codeout , if possible, can you please help me with implementing the following:

  • 1. When hovering over a link, increase the size of the label (interface)
  • 2. When hovering over a link, bring the label to the foreground (so that links are not on top of them)
  • 3. When hovering over a link, make a filled background for the label (if there are any links going under that label, it will not mess up the view)
  • 4. hover over label (I tried .path-label:hover and others, but did not work)
  • 5. If we can make all other labels invisible(except the one attached to the link/label) when hovering over a particular link (maybe a little farfetched??)

2 or more links between 2 nodes

Hi, I want to draw 2 or more links between 2 nodes to show trunk links.

For example, I prepared the JSON file like below:

{
  "nodes": [
    { "name": "node1" },
    { "name": "node2" }
  ],

  "links": [
    { "source": "node1",  "target": "node2", 
      "meta": {
        "interface": { "source": "Eth1", "target": "Eth1" }
      }
    },
    { "source": "node1",  "target": "node2",
      "meta": {
        "interface": { "source": "Eth2", "target": "Eth2" }
      }
    }
  ]
}

By this, I expect 2 links are drawn between Eth1 of each nodes and between Eth2 of them. But the result was like below:

screen shot 2018-04-05 at 16 52 50

It seems that 2 links are overlapping. Is my JSON file is incorrect? In case of that, how can I fix it?

Node name in pop

Hi,
Nice project for dynamic network map drawing 👍
Is it possible to remove pop name from node name in pop?
e.g. full node names in shownet.json is "dceast-ne40e", "dceast-fx1-1", they are grouped to pop "dceast", but individual nodes in pop "dceast" could be named "ne40e", "fx1-1"

Support for PortChannels ? (both classic and to two switches)

Hi, amazing project I was wondering if there is any possibility to implement drawing for portchannels, i know there is a BUNDLE option but I was wondering if we can improve graphic to both classic setup like from switch to switch and from one switch to two switches (as we have such topology in our environment)

Look at the ovals below ? Would it be hard to implement ? Can I do it by myself ?
image

Different meta in popup for different devices

Is there a way to display different meta for different Nodes ?
E.g. I have two nodes, one is router one is switch, both have different meta but I dont want to write all meta in Diagram init.

{
  "name": "Router",
  "meta": {
    "name": "router1",
    "hostname": "test",
    "tenant-ip": "123456,
    "admin-ip": "1.1.1.1",
    "loopback-ip": "2.2.2.2",
    "serial-number": "897564SDWQ",
    "ios-version": "16.12.2s",
    "software-type": "ios-xe",
    "hypervisor-hostname": "ESX123",
    "hypervisor-ip": "10.10.10.10",
    etc...
  },
  "icon": "../images/ios-xe.png"
},
{
  "name": "Switch",
  "group": "POD1",
  "meta": {
    "capabilities": "",
    "childAction": "",
    "clientEvent": "assigned",
    "configIssues": "",
etc...
  },
  "icon": "../images/nexus9k.png"
},

Group nodes base on meta

Hi
Awsome project
Would it be posible to group nodes base on meta of the node

    { "name": "192.168.3.63", "icon": "./images/server.png", "meta": { "grouping": "GRP1" } },
    { "name": "192.168.35.72", "icon": "./images/server.png", "meta": { "grouping": "GRP1" } },
    { "name": "192.168.18.78", "icon": "./images/server.png", "meta": { "grouping": "GRP1" } },
    { "name": "192.168.18.79", "icon": "./images/server.png", "meta": { "grouping": "GRP1" } },
    { "name": "192.168.35.71", "icon": "./images/server.png", "meta": { "grouping": "GRP1" } },
    { "name": "192.168.35.120", "icon": "./images/server.png", "meta": { "grouping": "GRP1" } },
    { "name": "192.168.32.142", "icon": "./images/server.png", "meta": { "grouping": "GRP2" } },
    { "name": "192.168.3.177", "icon": "./images/server.png", "meta": { "grouping": "GRP2" } },
    { "name": "192.168.3.176", "icon": "./images/server.png", "meta": { "grouping": "GRP2" } },
    { "name": "192.168.3.175", "icon": "./images/server.png", "meta": { "grouping": "GRP2" } },

Thank you

Internal group

Im implementing network diagram using internal groups features.
2 main groups (in each main group that contain 2-3 internal group).
I got the following trouble:

  1. it is not smoothly to moving node of network diagram .
  2. When i added more node,The rendered network diagram like dancing.

In your wiki, i figured out that is still a experimental Features.
Could you tell me when final version of this feature is release?
OR what should i do to make up these issues

POP object query

Hi,

1st of all thank you for such a great tool!

My question is around POP grouping, is it possible (I guess this is a feature request) to make it upper case? All of my devices are lower case and POP name is last three characters (vs example) or maybe even override this behaviour with own names?

Thank you.

Bug translate

I use
diagram.svg.attr('transform', 'translate(100, 100) scale(1.5)');
It turns out to move the map. but when you try to move the map, you jump to the coordinates before moving

Add an optional meta field

Hi,

Is it possible to request a meta field for link state? would be nice to be able to show links in UP/DOWN, i'm pulling data from NMS to generate topology so would be able to push this too and display nicely on the map.

P.S: is there a way of offsetting / aligning interface description to middle of the link?

Thank you.

Please add escape functions for Node manipulation

Because we have many connections between nodes, I decided I will use network as node.
But encountered error in tooltip because there are special characters like dots and slash in subnet.

Decided to use, you might add CSS.escape to the tooltip.ts.
I solved it with this below.

nodeId(): string {
        return classify(CSS.escape((<Node>this.node).name));
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.