Dynamically change Link category with multiple link templates


#1

Hi
I have multiple link templates in one diagram.
how to change a link category for particular link at certain logic point.
and link should take effect (refreshing) immediately.
trying to use model.setCategoryForLinkData but it is warn me as unexist method. I am using go.js version 1.8.31.

 this.diagram.model.setCategoryForLinkData(linkData, 'subRedLink');

and snippet suggest me to use setCategoryForNodeData because it is not exist.

even I refer Switching Between Links after Link Drawn Based On Node's Data
and Use different type of links between certain ports.

can anyone help me out.

Thanks


#2

If your Diagram.model is an instance of GraphLinksModel, that call should be correct. However the type of Diagram.model is just Model, which does not have that method defined, so if you care, you should cast this.diagram.model to a GraphLinksModel.

But in any case you should be executing that statement within a transaction. Are you conducting a transaction at that time?


#3

when diagram Inits model takes a GraphLinksModel when feeding data to model it is from JSON so it looks like

// when initialize      
this.diagram.model =
  $(go.GraphLinksModel,
    {
      linkFromPortIdProperty: 'fromPort',
      linkToPortIdProperty: 'toPort',
      nodeKeyProperty: 'uuid',
      linkKeyProperty: 'uuid'
    });

....... some code...........
// when feed nodes and links
this.diagram.model = go.Model.fromJson(this.common.currentDiagramBuilder.diagramJSON);

yes this statement is executing under transaction.

 this.diagram.model.setCategoryForLinkData(linkData, 'subRedLink');

#4

So what is your question? What is the problem?


#5

I am not able to change category of link and its not refresh at a time.


#6

OK, so the model is an instance of GraphLinksModel, so the call does not result in an error, but it does not have any effect either. I do not understand about a warning – what was that?

So you need to debug this. Are you using the go-debug.js library?

What is the value of linkData? And what is the value of linkData.category, both before and after the call?

Is the value of myDiagram.linkTemplateMap.get("subRedLink") a different link template than the template named by the previous category name?


#7

Hi,
the warning is

the value of linkData before transaction is

from: "7710e149810b"
fromPort: "PS1"
redlinkid: ""
to: "476cba569526"
toPort: "0"
uuid: "458fe168dfd0"

after transaction the values are

category: "subRedLink"
from: "7710e149810b"
fromPort: "PS1"
redlinkid: "758cb1a70d01"
to: "476cba569526"
toPort: "0"
uuid: "458fe168dfd0"

previous template is default template there is no any category. after this transaction program provide a category to it.

when I reload the diagram then it works as need.


#8

That’s not a run-time warning, but an edit-time message from the language extension system pointing out that the Model class, the type of the Diagram.model property, does not support that method. But that has no effect on the run-time behavior, so you can ignore it.

No “category” property means it uses the default link template. Do you have a different link template named “subRedLink” in the Diagram.linkTemplateMap?


#9

ok. yes I have different link template in template-map for subRedLink


#10

Here’s an example that works: https://codepen.io/jhardy/pen/xmgJgw?editors=1010

What are you doing differently?


#11

Hi jhardy,
here I am changing category according to your sample but a link isnt refreshing.

here is my Link template

this.diagram.linkTemplateMap.add('subRedLink',
      $(SubRedLinkPath,
        {
          adjusting: go.Link.End,
          corner: 15
        },
        $(go.Shape, shapeStyle(),  // the link path shape
          { isPanelMain: true, strokeWidth: 5 }), {
          selectionAdornmentTemplate:
            $(go.Adornment,
              $(go.Shape,
                { isPanelMain: true, stroke: 'dodgerblue', strokeWidth: 10 })
            ) 
        }
      ));

and this is a subRedLink class with extended link class

 import * as go from 'gojs';

export class SubRedLinkPath extends go.Link {
constructor() {
    super();
    go.Link.call(this);
}

computePoints() {
    if (this.data.redlinkid) {
        const start = this.getLinkPointFromPoint(this.fromNode,
            this.fromPort, this.fromPort.getDocumentPoint(go.Spot.Center), new go.Point(0, 0), true);
        const end = this.getLinkPointFromPoint(this.toNode,
            this.toPort, this.toPort.getDocumentPoint(go.Spot.Center), new go.Point(0, 0), false);
        let redLink;
        this.clearPoints();
        this.diagram.links.each(link => {
            if (link.data.uuid === this.data.redlinkid) {
                redLink = link;
            }
        });
        this.points.push(start);
        redLink.points.each(element => {
            this.points.push(element);
        });
        this.points.push(end);
    }
    return true;
}

}

question is when I am changing category of link it should be take this template and take effects on link points.


#12

Ahh, so you’re not just changing the category, you’re also changing the class. Generally, when making such changes, you want to replace the link rather than just changing the category. I’m surprised there wasn’t a warning message that came up when you tried running this, I was given one. This way all the necessary functions will run using the new Link subclass.


#13

you mean to say instead of changing category create new link with same data?
even I am getting error while build this.


#14

Yes, create a new link with the extra properties and delete the old one.

Just so you know, you can resolve build errors like that by casting:

(this.diagram.model as go.GraphLinksModel).setCategoryForLinkData(...)

since you know you have a GraphLinksModel in this case.


#15

I don’t know that the code is TypeScript, so that might not work.

The idea is that we cannot change the class of an existing GraphObject, but you can replace it with an instance of what you want. You definitely should have gotten a message about it in the console, even if you were using go.js rather than the usual go-debug.js when debugging.


#16

Thanks jhardy and walter. replacing a link it works. can use go-debug.js while running with npm packages in angular?


#17

Yes, use a relative path in the import statement.