Custom RulesProvider

Hi,

in the abstract RuleProvider from diagram-js its written that the rules return true or false or nothing. So its basically a check if the corresponding command handler should be applied or not.

But in BpmnRules.js there is a rule for connection.create. The callback contains amongst others return canConnect(source,target). The canConnect method returns amongst others
return { type: 'bpmn:MessageFlow' }.

I understand that this is needed to draw the right connection. But this is not consistent to my first line that it should return a boolean. I have taken a look to the source code of diagram-js und don’t understand where this return value is used. At the end, this return value is necessary for the drawConnection call from the BpmnRenderer to get the correct handler.

Do i understand something wrong?

In JavaScript every object is true. The returned object of canConnect is not used in this case.

1 Like

Are you sure that the returned object is not used? I don’t think so.
The BpmnRenderer.js uses the returned object (here the type of the connection) to get the right handler in his drawConnection method.

You see there the following code:

var type = element.type; var h = this.handlers[type];

You are right, that the canConnect method abuse the return value of RuleProvider to find out what type of connection it is. Its imo build mainly for the global-connect feature. It is used in the snapping module of bpmn-js to assign the type.

I don’t get exactly what your problem is. What are you trying to do?

I want to understand why it returns the type of the connection. Is there any ‘cleaner’ way to set the type for the connection instead of using the RuleProvider?

I’m writing my own extension of diagram-js. So far so good, but i want to support different types of connections. In the context pad the user should be able to select the connection type he wants. My ContextPadProvider contains an action to connect the selected element with another. Same mechanic like in bpmn-js, it uses the ConnectModule, i.e. the start(event, element) method.
But anywhere i need to set the type of this connection (the Renderer uses this in his drawConnection method), but i won’t to add this to the RuleProvider because of the already mentioned reasons.

Like I said, the canConnect method in the Connect module isn’t using the return type, except for checking if it can connect or not. The snapping module in bpmn-js is abusing the Rule behavior as a ‘ConnectionFactory’. To specify the type of your Element you could

  1. write your own Connect module, which knows the type of connections
  2. specify the type in the Snapping module, like bpmn-js is doing it, without using the Rule as a Factory

I want in my context pad for instance 4 different entries where the user can select a type of line.

'inheritance-connect': {
  group: 'connect',
  className: 'context-pad-icon-inheritance-connect',
  title: 'Inheritance Connection',
  action: {
    click: connect('inheritance'),
    dragstart: connect('inheritance')
  }

'association-connect': {
  group: 'connect',
  className: 'context-pad-icon-association-connect',
  title: 'Association Connection',
  action: {
    click: connect('association'),
    dragstart: connect('association')
  }

and so on. The connect method now creates the appropriate connections.

Maybe i could just use the Modeler or elementFactory in the connect method to create the connection and then set the type
connection.type = 'inheritance'.

If I understand correctly you want to be able to specify the type of connection when connecting instead of letting Connect decide about the type of connection. The reason why we do this is to simplify connecting elements. According to the BPMN specification there is only one possible type of connection between any two BPMN elements. Therefore bpmn-js determines the type of connection automatically. If your domain allows more than one type of connection between two given elements you can change the context pad to have different entries for different types of connections.

Exactly. Take for instance UML class diagrams. Classes are represented by rectangles and we have different types of connections, i.e. inheritance, aggregation, dependency, etc.

Now the context pad should contain an entry for every type of connection as you already mentioned. Is my approach from above right?

So when i implement a connect(type) method i have to use the elementFactory or modeler to create the connection? I would take the elementFactory.

I’m creating a uml-js on top of diagram-js.

Implementing this behavior will take a bit of effort. At the moment, you cannot tell Connect the type of connection you want and in addition to that the rule for connection.create would have to evaluate source, target AND the desired type of connection. With these modifications you should get the desired behavior.

1 Like

Thanks, works now. :slight_smile:

1 Like

HI, I meet the same issu.
Can you post code solution ?
Thanks a lot.