Skip to content

Possible solution for hierarchical design #27

@stefan-ma22

Description

@stefan-ma22

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions