Skip to content

Instantly share code, notes, and snippets.

@gmkado
Created August 13, 2020 18:11
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gmkado/ab12ea0d0b5dbf589ec39b1b221f51d5 to your computer and use it in GitHub Desktop.
Save gmkado/ab12ea0d0b5dbf589ec39b1b221f51d5 to your computer and use it in GitHub Desktop.
Generate the points style string necessary to add points to a shape in drawio
import numpy as np
def pt_str(x,y):
return f'[{x:.2f}, {y:.2f}]'
# SET THESE TO THE NUMBER OF POINTS YOU NEED
top = 0
left = 0
right = 13
bottom = 0
pts = []
if top:
xs = np.linspace(0, 1, top)
y = 0
pts += [pt_str(x,y) for x in xs]
if bottom:
xs = np.linspace(0, 1, bottom)
y = 1
pts += [pt_str(x,y) for x in xs]
if left:
x = 0
ys = np.linspace(0, 1, left)
pts += [pt_str(x,y) for y in ys]
if right:
x = 1
ys = np.linspace(0, 1, right)
pts += [pt_str(x,y) for y in ys]
pts_str = ','.join(pts)
print(f'points=[{pts_str}]')
@sanuness
Copy link

Thanks.
It helped me a lot. Now I can create a box out of an image and connect at these points.

@kammoh
Copy link

kammoh commented Apr 24, 2021

Thank for sharing your response and code. Here's a slightly modified version of this code.

The centered option:

In many cases, for example when creating logic circuit diagrams, I need the waypoints to be centered in the edges and exclude the vertice end-points. This can be set to False to include the vertex.

import numpy as np

def drawio_connections(top=0, bottom=0, left=0, right=0, centered=True):
    def pt_str(x,y):
        return f'[{x:.2f},{y:.2f}]'

    def get_points(x):
        ls = np.linspace(0, 1, x+2 if centered else x)
        return ls[1:-1] if centered else ls

    pts = [pt_str(x,0) for x in get_points(top)]
    pts += [pt_str(x,1) for x in get_points(bottom)]
    pts += [pt_str(0,y) for y in get_points(left)]
    pts += [pt_str(1,y) for y in get_points(right)]
    return f'points=[{",".join(pts)}];'

drawio_connections(top=1,bottom=4,left=3)

gives:

points=[[0.50,0.00],[0.20,1.00],[0.40,1.00],[0.60,1.00],[0.80,1.00],[0.00,0.25],[0.00,0.50],[0.00,0.75]];

This is what I get If I apply it to a parallelogram (representing a Multiplexer). Exactly what I wanted!
image

@ben-geee
Copy link

ben-geee commented Sep 1, 2021

Both very cool and helpful solutions! Thank you for sharing!

@ben-geee
Copy link

ben-geee commented Sep 2, 2021

So, I also added some code. And plese be kind, I'm not into Python. 😄

import numpy as np

def drawio_connections(top=0, bottom=0, left=0, right=0, centered=True, mode="CSV", perimeter=False):
    def pt_str(x,y,mode):
      if mode == "CSV":
        if perimeter == True:
          return f'[{x:.2f},{y:.2f},1]'
        else:
          return f'[{x:.2f},{y:.2f}]'
      elif mode == "XML":
        if perimeter == True:
          return f'<constraint x="{x:.2f}" y="{y:.2f}" perimeter="1" />'
        else:
          return f'<constraint x="{x:.2f}" y="{y:.2f}" />'
      else:
        return ""

    def get_points(x):
        ls = np.linspace(0, 1, x+2 if centered else x)
        return ls[1:-1] if centered else ls

    pts = [pt_str(x,0,mode) for x in get_points(top)]
    pts += [pt_str(x,1,mode) for x in get_points(bottom)]
    pts += [pt_str(0,y,mode) for y in get_points(left)]
    pts += [pt_str(1,y,mode) for y in get_points(right)]
    
    if mode == "CSV":
      return f'points=[{",".join(pts)}];'
    elif mode == "XML":
      returnval = '\n'.join(pts)
      return f'{returnval}'
    else:
      return ""

print(drawio_connections(top=1,bottom=1,left=1,right=1,mode="XML"))

This script has two more options:

String mode, can be set to CSV or XML. CSV leads to the standard behaviour you already implemented. XML gives you the coordinates as XML structure to directly use them in shape definitions.

Gives

<constraint x="0.50" y="0.00" />
<constraint x="0.50" y="1.00" />
<constraint x="0.00" y="0.50" />
<constraint x="1.00" y="0.50" />

Minor important
Boolean perimeter, when set to True it adds perimeter as third attribute, which on some shapes interpolates the given point coordinate on the shape edge instead of the outline. Maybe I got it a little bit wrong, documentation was quite confusing on this.

<constraint x="0.25" y="0.00" perimeter="1" />
<constraint x="0.50" y="0.00" perimeter="1" />

or

points=[[0.25,0.00,1],[0.50,0.00,1],[0.75,0.00,1],[0.25,1.00,1],[0.50,1.00,1],[0.75,1.00,1],[0.00,0.25,1],[0.00,0.50,1],[0.00,0.75,1],[1.00,0.25,1],[1.00,0.50,1],[1.00,0.75,1]];

Cheers,
Ben

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment