BPMN Subprocess size problem in BPMN Example

Hi,

I wonder why is this happening? In BPMN example if I put subprocess activity and click on expand button everything is fine. Now if I resize a little bit this activity element and after that collapse it or expand it element looses expanded or collapsed size.

First case in picture is if I expand element and then resize node.

Second case if I resize a node before expanding.

Really, the subprocess should not be resizable, sorry about that. Because it’s a Group, its size should really be dependent on the Placeholder which contains the subgraph. We’ll update the sample to reflect this.

-Jon

Yes but even that will not solve the problem when we want to set node size setting size property of node.data. This element behave nicely only if size is set by template. Any setting of size after template is initialized will cause unwanted behavior like I described in previous post. It would be nice to have one size of collapsed node and another when it is expanded. And to have possibility to set node size when node is added to the diagram. At the moment the last one causes the same unwanted behavior of node during expand - collapse user action.

Ok, so it sounds like you want to keep some resizing. Could you outline exactly what behavior you are looking for during resizing, and maybe provide some screenshots of various scenarios?

-Jon

Generally I don’t need resizing as a user action possibility. But I need to use size property bind in data of subprocess node to get proper height and width of element (it is written in BPMN xml file). So what I want is that if I set size property inside node subprocess element of data array I need to get next. After parsing xml file diagram looks like:


After clicking on expand button I got:

So if I click again on subprocess button it will collapse and I will get state from first image.
This solution works if size of element is predefined in subprocess template. But if I want to set size through data binding it is wrong the same way as if I resize element using mouse (images from first post). Seems that some internal math of group size is broken if it is changed after template is instantiated, because I couldn’t find code responsible for this.

I hope this explanation is sufficient for you to find out what I want.

Best regards
Mickey

Do you only want to set the size for the collapsed group, or are you looking to set a size even when it’s expanded? Normally when the subgraph is expanded, the size would come from the nodes in the subgraph.

Yes I want only to set size of collapsed group (first image). When it is expanded its size will depend on member elements only and button. Possibly it could be nice if I can set position where expanded state will be positioned on diagram but size should be like on image 2.

I have another question and if I need to create a new topic on the forum just tell me. But as I remember in some previous version of GoJS it was possible to prevent that duplicate links are shown or even added to diagram (they were ignored by diagram model I think). Now I can’t find this info anywhere in docs. Can I do that using some GoJS property or I need manually to check if link exist and prevent creating new one?

Here’s a solution that will allow resizing only when the Group is collapsed. Replace the subProcessGroupTemplate with this, and be sure to keep the size variable declarations so the Group uses the correct Size once expanded.

var noSize = new go.Size(NaN, NaN);
var minSize = new go.Size(1, 1);

var subProcessGroupTemplate =
  $(go.Group, "Spot",
    { 
      locationSpot: go.Spot.Center,
      locationObjectName: "PH",
      //locationSpot: go.Spot.Center,
      isSubGraphExpanded: false,
      resizable: true, resizeObjectName: "PH",
      memberValidation: function(group, part) {
        return !(part instanceof go.Group) ||
               (part.category !== "Pool" && part.category !== "Lane");
      },
      mouseDrop: function(e, grp) {
        var ok = grp.addMembers(grp.diagram.selection, true);
        if (!ok) grp.diagram.currentTool.doCancel();
      },
      contextMenu: activityNodeMenu,
      itemTemplate: boundaryEventItemTemplate
    },
    new go.Binding("itemArray", "boundaryEventArray"),
    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
    // move a selected part into the Foreground layer, so it isn't obscured by any non-selected parts
    // new go.Binding("layerName", "isSelected", function (s) { return s ? "Foreground" : ""; }).ofObject(),
    $(go.Panel, "Auto",
      new go.Binding("visible", "isSubGraphExpanded", function(v) { return !v; }).ofObject(),
      new go.Binding("desiredSize", "isSubGraphExpanded", function(v) { return v ? minSize : noSize; }).ofObject(),
      $(go.Shape, "RoundedRectangle",
        {
          name: "PH", fill: SubprocessNodeFill, stroke: SubprocessNodeStroke,
          minSize: new go.Size(ActivityNodeWidth, ActivityNodeHeight),
          portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer",
          fromSpot: go.Spot.RightSide, toSpot: go.Spot.LeftSide
        },
        new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
        new go.Binding("strokeWidth", "isCall", function(s) { return s ? ActivityNodeStrokeWidthIsCall : ActivityNodeStrokeWidth; })
      ),
      $(go.Panel, "Vertical",
        { defaultAlignment: go.Spot.Left },
        $(go.TextBlock,  // label
          { margin: 3, editable: true, alignment: go.Spot.Center },
          new go.Binding("text", "text").makeTwoWay()
        ),
        makeMarkerPanel(true, 1)  // sub-process,  loop, parallel, sequential, ad doc and compensation markers
      )  // end Vertical Panel
    ),
    $(go.Panel, "Auto",
      new go.Binding("visible", "isSubGraphExpanded").ofObject(),
      $(go.Shape, "RoundedRectangle",
        {
          fill: SubprocessNodeFill, stroke: SubprocessNodeStroke,
          minSize: new go.Size(ActivityNodeWidth, ActivityNodeHeight),
          portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer",
          fromSpot: go.Spot.RightSide, toSpot: go.Spot.LeftSide
        },
        new go.Binding("strokeWidth", "isCall", function(s) { return s ? ActivityNodeStrokeWidthIsCall : ActivityNodeStrokeWidth; })
      ),
      $(go.Panel, "Vertical",
        { defaultAlignment: go.Spot.Left },
        $(go.TextBlock,  // label
          { margin: 3, editable: true, alignment: go.Spot.TopLeft },
          new go.Binding("text", "text").makeTwoWay()
        ),
        // create a placeholder to represent the area where the contents of the group are
        $(go.Placeholder,
          { padding: new go.Margin(5, 5) }),
        makeMarkerPanel(true, 1)  // sub-process,  loop, parallel, sequential, ad doc and compensation markers
      )  // end Vertical Panel
    )
  );  // end Group

The idea here is to use two different Panels to handle resizing/setting desiredSize and set the visibility of these Panels based on the isSubGraphExpanded property.

-Jon

Resizing is fine now. But I have one issue with this solution. After collapsing subprocess from link keeps to be connected to expanded node geometry not collapsed. In BPMN example that not happen but in my BPMN viewer which is based on this example I have a problem. If you go to this address http://ec2-54-174-98-183.compute-1.amazonaws.com:8888/MPDesigner/ and click on third tab (BPMN) and then test2 button. Expand and collapse subprocess and you will see what am I talking about.

It looks like the problem is related to ports. Have you changed the setup for ports in your code compared to the normal BPMN sample where the links are working properly?

I think not but if you tell me what parts of code is responsible for that I can check and tell you more.

Actually, that may not be the problem. We’ll take a look and see if we can track down what’s causing the linking issues with these groups.

After some debugging, we noticed that you seem to be running version 1.6.13 of GoJS. Using the same templates/model with 1.6.18 produces correct links, so upgrading your version will resolve your issue.

-Jon

Perfect. This is it. Thanks.

One more thing. Can you tell me why subprocess element changes it’s position only after first expand / collapse? After that any change of node position is properly restored after collapse except for the first time.

The reason this is happening is because the location of the Group and its child Nodes don’t correspond in the data. When the Group is first expanded, the Placeholder adjusts itself to fit around all children’s locations and sets the Group’s position based upon that.

There are a couple ways to deal with this:
a) Use a Layout within the Group to place the children. This means any location changes made to the children will be lost upon collapsing/expanding the Group. Depending on your usage, that may not be an issue.
b) Adjust the data such that the hardcoded locations coincide with one another to avoid having the Group moving when it first expands.

-Jon

Even if I use layout for group it didn’t helped. But anyway I don’t need this solution. I tried second solution and it worked when I changed binding for location to be bind to position:

new go.Binding(“position”, “loc”, go.Point.parse).makeTwoWay(go.Point.stringify),

After that I did some math to reposition members of group and it is working. Only issue I have that outer link is not restored as is was before expanding. I will update app on server so you can check visually what I’m trying to describe.

That should be resolved when you upgrade to the latest version as discussed yesterday.

But I updated release folder with lastes gojs.js. Everything else is from older version. But on my development computer I updated whole gojs through npm update and I have the same result. Are you sure that this problem is about older version?