Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question/Suggestion] NOT an issue #1

Closed
jpobeda opened this issue Oct 8, 2020 · 6 comments
Closed

[Question/Suggestion] NOT an issue #1

jpobeda opened this issue Oct 8, 2020 · 6 comments

Comments

@jpobeda
Copy link

jpobeda commented Oct 8, 2020

Hi there,

First of, thanks for this work, I found out we've done the same only that yours is awesome and reusable and mine was script style hehe.

It's good to see that you actively adding more stuff. I thought it was a one off thing and wouldn't be any more updates and I started to refactor it on a local repo on my machine.

I see you've added src_label and target_label but in a different way of how I've done it.

Following the string declarations for nodes and links I went down this path

XML String
    # source edge label x="-0.5" y="1"
    drawio_link_source_label_xml = """
      <mxCell id="{id}" value="{value}" style="{style}" parent="{parent}" vertex="1" connectable="0">
          <mxGeometry x="-0.5" y="1" relative="1" as="geometry">
            <mxPoint as="offset"/>
          </mxGeometry>
      </mxCell>
    """

    # target edge label x="0.5" y="-1"
    drawio_link_target_label_xml = """
      <mxCell id="{id}" value="{value}" style="{style}" parent="{parent}" vertex="1" connectable="0">
          <mxGeometry x="0.5" y="-1" relative="1" as="geometry">
            <mxPoint as="offset"/>
          </mxGeometry>
      </mxCell>
    """

And then something like below, basically assuming that if you pass a src_label there will be target_label, otherwise just pass label.

Python Code
if src_label != '' and tgt_label != '':
            src_id = f"{edge_id}-src"
            tgt_id = f"{edge_id}-tgt"
            source_label = ET.fromstring(
                self.drawio_link_source_label_xml.format(
                    id=f"{edge_id}-src",
                    value=src_label,
                    parent=edge_id,
                    style=style if style else self.default_link_style,
                )
            )
            target_label = ET.fromstring(
                self.drawio_link_target_label_xml.format(
                    id=f"{edge_id}-tgt",
                    value=tgt_label,
                    parent=edge_id,
                    style=style if style else self.default_link_style,
                )
            )
        else:
            source_label = None
            target_label = None

The XML should look like below, I'm adding a suffix -src and -tgt to the link id.

Output XML
<object label="" id="2d123edf1f03cdcb18fa393bc8d1e719">
          <mxCell style="endArrow=none;" parent="1" source="R1" target="SW1" edge="1">
            <mxGeometry relative="1" as="geometry" />
          </mxCell>
        </object>
        <mxCell id="2d123edf1f03cdcb18fa393bc8d1e719-src" value="G1/0/1" style="endArrow=none;" parent="2d123edf1f03cdcb18fa393bc8d1e719" vertex="1" connectable="0">
          <mxGeometry x="-0.5" y="1" relative="1" as="geometry">
            <mxPoint as="offset" />
          </mxGeometry>
        </mxCell>
        <mxCell id="2d123edf1f03cdcb18fa393bc8d1e719-tgt" value="Eth1/1/1" style="endArrow=none;" parent="2d123edf1f03cdcb18fa393bc8d1e719" vertex="1" connectable="0">
          <mxGeometry x="0.5" y="-1" relative="1" as="geometry">
            <mxPoint as="offset" />
          </mxGeometry>
        </mxCell>

Ignoring the style, the picture below illustrates what I mean.

DrawIO Diagram output

github-issue

Additionally I found it a lot easier for my use cases to have a yaml file with styles where I can basically declare more entries on each dict for customization instead of having multiple txt files.

YAML Code
shapes_map:
  'bus': 'shape=mxgraph.networks.bus;fillColor=#d5e8d4;strokeColor=#82b366;outlineConnect=0;strokeWidth=2;gradientColor=none;gradientDirection=north;perimeter=backbonePerimeter;backboneSize=20;glass=0;'
  'firewall': 'shape=mxgraph.office.concepts.firewall;fillColor=#DA4026;strokeColor=none;outlineConnect=0;aspect=fixed;'
  'hafirewall': 'shape=mxgraph.office.concepts.firewall;fillColor=#DA4026;aspect=fixed;'
  'router': 'shape=mxgraph.cisco19.rect;prIcon=router;fillColor=#FAFAFA;strokeColor=#005073;aspect=fixed;'
  'access switch': 'shape=mxgraph.cisco19.rect;prIcon=l2_switch;fillColor=#FAFAFA;strokeColor=#005073;align=center;outlineConnect=0;aspect=fixed;'
  'management switch': 'shape=mxgraph.vvd.switch;strokeColor=none;fillColor=#434445;align=center;outlineConnect=0;aspect=fixed;'
  'core switch': 'shape=mxgraph.cisco19.rect;prIcon=secure_catalyst_switch_color2;fillColor=#FAFAFA;strokeColor=#005073;aspect=fixed;'
  'distribution switch': 'shape=mxgraph.cisco19.rect;prIcon=l3_switch;fillColor=#FAFAFA;strokeColor=#005073;aspect=fixed;'
  'server': 'shape=mxgraph.aws3.traditional_server;fillColor=#7D7C7C;strokeColor=#67AB9F;outlineConnect=0;'
  'cloud': 'shape=mxgraph.cisco19.cloud2;fillColor=#FFE9AA;strokeColor=none;aspect=fixed;'
  'cluster': 'shape=mxgraph.veeam.cluster;rounded=1;fillColor=#ffe6cc;strokeColor=#d79b00;aspect=fixed;'
  'workstation': 'shape=mxgraph.signs.tech.computer;fillColor=#000000;strokeColor=none;'
  'other': 'whiteSpace=wrap;html=1;rounded=1;verticalLabelPosition=bottom;verticalAlign=top;align=center;aspect=fixed;'
  'ont': 'mxgraph.cisco.modems_and_phones.cable_modem;html=1;dashed=0;fillColor=#036897;strokeColor=#ffffff;strokeWidth=2;'
  'media converter': 'mxgraph.cisco.modems_and_phones.cable_modem;html=1;dashed=0;fillColor=#036897;strokeColor=#ffffff;strokeWidth=2;'
  'storage': 'mxgraph.cisco_safe.compositeIcon;bgIcon=ellipse;resIcon=mxgraph.cisco_safe.capability.storage;fillColor=#999999;html=1;strokeColor=#ffffff;aspect=fixed;'
  'hardware security modules': 'mxgraph.cisco_safe.compositeIcon;bgIcon=ellipse;resIcon=mxgraph.cisco_safe.capability.secure_server;rounded=1;glass=0;fillColor=#999999;strokeColor=#ffffff;aspect=fixed;'

shapes_label:
  'bus': 'labelBackgroundColor=none;labelPosition=middle;align=center;html=1;fontStyle=1;fontSize=13;fontColor=#000000;'
  'bus_vertical': 'labelBackgroundColor=none;labelPosition=left;verticalLabelPosition=middle;align=rigth;verticalAlign=middle;html=1;fontColor=#000000;spacingTop=999;spacing=0;direction=west;horizontal=0;spacingBottom=-365;'
  'firewall': 'labelBackgroundColor=none;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontSize=13;fontColor=#0066CC;'
  'hafirewall': 'labelBackgroundColor=#004C99;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#D4D4D4;'
  'router': 'labelBackgroundColor=#004C99;;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#D4D4D4;'
  'access switch': 'labelBackgroundColor=none;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontSize=13;fontColor=#0066CC;'
  'management switch': 'labelBackgroundColor=none;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontSize=13;fontColor=#0066CC;'
  'core switch': 'labelBackgroundColor=#99CCFF;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#000000;'
  'distribution switch': 'labelBackgroundColor=none;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#0066CC;'
  'server': 'labelBackgroundColor=none;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#0066CC;'
  'cloud': 'labelBackgroundColor=#004C99;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#D4D4D4;'
  'cluster': 'labelBackgroundColor=none;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#0066CC;'
  'workstation': 'verticalLabelPosition=bottom;verticalAlign=top;align=center;'
  'other': 'labelBackgroundColor=none;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#0066CC;'
  'ont': 'labelBackgroundColor=#99CCFF;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#000000;'
  'media converter': 'labelBackgroundColor=#99CCFF;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#000000;'
  'storage': 'labelBackgroundColor=none;verticalLabelPosition=bottom;labelPosition=center;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#000000;'
  'hardware security modules': 'labelBackgroundColor=#99CCFF;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacing=2;fontStyle=1;fontSize=13;fontColor=#000000;'

shapes_size:
  'bus': {'width': '1435', 'height': '20'}
  'firewall': {'width': '47', 'height': '43'}
  'hafirewall': {'width': '47', 'height': '43'}
  'router': {'width': '50', 'height': '50'}
  'access switch': {'width': '50', 'height': '50'}
  'management switch': {'width': '50', 'height': '50'}
  'core switch': {'width': '50', 'height': '50'}
  'distribution switch': {'width': '50', 'height': '50'}
  'server': {'width': '46', 'height': '60'}
  'cloud': {'width': '60', 'height': '60'}
  'cluster': {'width': '60', 'height': '60'}
  'workstation': {'width': '68', 'height': '68'}
  'other': {'width': '60', 'height': '60'}
  'ont': {'width': '60', 'height': '30'}
  'media converter': {'width': '60', 'height': '30'}
  'storage': {'width': '43', 'height': '43'}
  'hardware security modules': {'width': '70', 'height': '70'}

Thoughts?

@dmulyalin
Copy link
Owner

Hi,

Thanks for kind words, glad to hear that you enjoying N2G.

Regarding link labels for drawio module, was not able to figure out how to position them properly along the edge so that behaviour would be deterministic, hence decided to encode src and trgt details in link data instead.

<mxCell id="2d123edf1f03cdcb18fa393bc8d1e719-src" value="G1/0/1" style="endArrow=none;" parent="2d123edf1f03cdcb18fa393bc8d1e719" vertex="1" connectable="0">
          <mxGeometry x="-0.5" y="1" relative="1" as="geometry">
            <mxPoint as="offset" />
          </mxGeometry>
        </mxCell>
        <mxCell id="2d123edf1f03cdcb18fa393bc8d1e719-tgt" value="Eth1/1/1" style="endArrow=none;" parent="2d123edf1f03cdcb18fa393bc8d1e719" vertex="1" connectable="0">
          <mxGeometry x="0.5" y="-1" relative="1" as="geometry">
            <mxPoint as="offset" />
          </mxGeometry>

mxGeometry x and y values, have you calculated them somehow automatically or they are just a result of manual edit?

Also, had a look at yed demo to get what I mean about proper source and target label auto positioning - yed handles it for you, while drawio seems to lack such a functionality.

Reason why I added src_label and trgt_label to drawio is to make API more consisted, so that I can supply same data structures to yed and drawio modules simelteniously making as much use of it as I can without adding any significat overhead required to
manually position things on the diagram.

Regarding styles - think you can supply them to drawio module as a python variables instead of text files:

from N2G import drawio_diagram

building_style="shape=mxgraph.cisco.buildings.generic_building;html=1;pointerEvents=1;dashed=0;fillColor=#036897;strokeColor=#ffffff;strokeWidth=2;verticalLabelPosition=bottom;verticalAlign=top;align=center;outlineConnect=0;"

diagram = drawio_diagram()
diagram.add_diagram("Page-1")
diagram.add_node(id="HQ", style=building_style, width=90, height=136)

In your case of YAML dictionary it would be something like this:

yaml_dict = {...}

shape_name = "firewall"
diagram.add_node(
    id="FW1", 
    style=yaml_dict["shapes_map"][shape_name ], 
    **yaml_dict["shapes_size"][shape_name ]
)

I deliberately omitted drawio styles from N2G, as do not want to maintain them if any changes would be done by DrawIO developers, also, yaml dictionary you did seems a good way of doing that, would rather leave it to users to define such a mappings for their specific use cases.

@dmulyalin
Copy link
Owner

re-read you comment, looks like you adding link labels positions in the xml template, hardcoding them to certain values,. These values, do they always produce good label placement results on the links?

@jpobeda
Copy link
Author

jpobeda commented Oct 11, 2020

Hi,

I chose those values because they seem to be work fine for that I do which are mostly L1/L2/L3 diagrams. They are offset values so they'll adjust to distance. The closest you set the shapes to one another the closest the labels get to the source or target and vice versa. See picture below

github-issue2
Now I moved R4 further down and the labels re-adjust.
github-issue3

Answering your question, they're good enough for me. At the end what I want is to be able to automatically generate them and being able to edit them.

N2G code
diagram = drawio_diagram()
diagram.add_diagram("Page-1")
c_style = "edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeColor=#0066CC;strokeWidth=2;"
diagram.layout(algo="kk")
diagram.add_link("R1", "SW1", style=c_style, src_label=f"Gi1/0/1", tgt_label="Te1/2/1")
diagram.add_link("R2", "SW1", style=c_style, src_label=f"Gi1/0/1", tgt_label="Te1/2/2")
diagram.add_link("R3", "SW1", style=c_style, src_label=f"Gi1/0/1", tgt_label="Te1/2/3")
diagram.add_link("R4", "SW1", style=c_style, src_label=f"Gi1/0/1", tgt_label="Te1/2/4")
diagram.add_link("R5", "SW1", style=c_style, src_label=f"Gi1/0/1", tgt_label="Te1/2/5")
diagram.add_link("R6", "SW1", style=c_style, src_label=f"Gi1/0/1", tgt_label="Te1/2/6")
diagram.add_link("MGMT", "R1", style=c_style, src_label=f"Gi1/0/1", tgt_label="Te1/2/6")

@dmulyalin I really like the drawio Organic layout algo, do you know where it comes from? I haven't tested yed. Do you reckon is a better prospect than drawio?

Sorry for the late response, I was out of town :)
Cheers,

@dmulyalin
Copy link
Owner

dmulyalin commented Oct 13, 2020

Thank you for your feedback, added support for src_label and trgt_label link attributes to DrawIO module, commit - 881f467

Regarding layout algorithms, have a look at Yed graph editor, it has very helpful features and layouts to speed nodes, links and labels arrangements.

Thanks for sharing your ideas and code samples with me to improve N2G.

@jpobeda
Copy link
Author

jpobeda commented Oct 14, 2020

Hi @dmulyalin I'll give it a go and let you know. Thanks

@jpobeda
Copy link
Author

jpobeda commented Oct 14, 2020

Worked perfectly! @dmulyalin , Denis right?

In [3]: diagram = drawio_diagram()
In [4]: diagram.add_diagram("Page-1")
In [5]: c_style = "edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeColor=#0066CC;strokeWidth=2;"
In [6]: diagram.add_link("R1", "SW1", style=c_style, src_label=f"Gi1/0/1", trgt_label="Te1/2/1")
In [7]: diagram.add_link("R2", "SW1", style=c_style, src_label=f"Gi1/0/1", trgt_label="Te1/2/2")
In [8]: diagram.add_link("R3", "SW1", style=c_style, src_label=f"Gi1/0/1", trgt_label="Te1/2/3")
In [9]: diagram.add_link("R4", "SW1", style=c_style, src_label=f"Gi1/0/1", trgt_label="Te1/2/4")
In [10]: diagram.add_link("R5", "SW1", style=c_style, src_label=f"Gi1/0/1", trgt_label="Te1/2/5")
In [11]: diagram.add_link("R6", "SW1", style=c_style, src_label=f"Gi1/0/1", trgt_label="Te1/2/6")
In [12]: diagram.add_link("MGMT", "R1", style=c_style, src_label=f"Gi1/0/1", trgt_label="Te1/2/6")
In [13]: diagram.dump_file(filename="github-issue1.drawio", folder="./output/")
In [14]: diagram.layout(algo="kk")
In [15]: diagram.dump_file(filename="github-issue1.drawio", folder="./output/")

I moved shapes around a bit to look at the labels position.

github-issue4

Just a note a side, I had to install ttp due to the new lldp_drawer module, don't forget to add that to the docs :D

Cheers,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants