Adding ports to shapes

Hey, Lately I have been experimenting with diagram-js to create my custom editor.
In my use case, I need ports to my shape ( example below ). These ports are the only locations a shape can be connected to or from. In my example
ports are custom shapes that are attached to the attachers array of the host object.
I don’t really like this solution because it creates lots of additional shapes just to have this functionality. In case you know a better solution for this I would like to hear about it.

Screenshot 2022-03-23 102923

Hi, could you share the solution of how to create ports in diagram js

Here is how I added ports to my custom shapes and custom elements…
In principle, I was taking care, that child shapes for the ports are being created, when the dragged from the palette.

(snippet CustomPalette.js)
...
var storageBussObj = bpmnFactory.create("e:ElectricityStorage", { id: "storage1", name: "storageName1", maximumChargingPower: 1.23, maximumDischargingPower: 2.34 });
var storageShape = elementFactory.createShape({ type: "e:ElectricityStorage", businessObject: storageBussObj });      
          
var portElecInBussObjData = { 
        id: "electricityInletPort1", 
        name: "ElectricityInlet", 
        unit: "MW",
        elem: storageBussObj };
var portElecInBussObj = bpmnFactory.create("e:Port", portElecInBussObjData);
storageBussObj.electricityInlet = portElecInBussObj;
var portElecInShape = elementFactory.createShape({ type: "e:Port", businessObject: portElecInBussObj, parent: storageShape });  

var portElecOutBussObjData = { 
        id: "electricityOutletPort1", 
        name: "ElectricityOutlet", 
        unit: "MW",
        elem: storageBussObj };
var portElecOutBussObj = bpmnFactory.create("e:Port", portElecOutBussObjData);
storageBussObj.electricityOutlet = portElecOutBussObj;    
var portElecOutShape = elementFactory.createShape({ type: "e:Port", businessObject: portElecOutBussObj, parent: storageShape } );
  
create.start(event, [ storageShape , portElecInShape, portElecOutShape] );
...

An electricity storage, and the inlet (port number 1) and outlet (port number 2) are also linked to each other in ModdleElement space.

The shape for the inlet and the shape for the outlet are being figured out, when rendering the custom shapes.

(snippet CustomRenderer.js)
...
this.findPortByName = function(element, n) {
    var c;
    for (let childIter = 0; childIter < element.children.length; childIter++) {
      var iterChild = element.children[childIter];
      var bo = getBusinessObject(iterChild);
      if(bo.name == n) {
        c = iterChild;
        break;
      }
    }
    return c;
  }

  this.drawBattery = function(p, element) {

    var width = element.width, height = element.height;

    var port1 = this.findPortByName(element, "ElectricityInlet");
    var p1x = element.x + 0             - (port1.width  / 2);
    var p1y = element.y + (height / 2)  - (port1.height / 2);
    port1.x = p1x; 
    port1.y = p1y;

    var port2 = this.findPortByName(element, "ElectricityOutlet");
    var p2x = element.x + width         - (port2.width  / 2);
    var p2y = element.y + (height / 2)  - (port2.height / 2);
    port2.x = p2x; 
    port2.y = p2y;

    ...
}
...
1 Like

Thanks @supervollmilch for sharing your solution here :star_struck:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.