Toggle specific Link lines via button click

I have a diagram which looks like this basic wireframe. A root node with several connected nodes (Red), and some interconnections (Blue)

By default I want the Blue ‘interlinks’ to be hidden, and to be toggleable via a button.

My link data looks like this

{
    from: fromID,
    to: toID,
    interlink: true,
    visible: false
}

Is it possible to render out specific link lines based on their visible property in this way?

My toggle button will probably do something like:

linkDataArray.forEach(link => {
  if (link.interlink) link.visible = !link.visible
});

First, you should realize that there is a difference between a Node or a Link being visible (or not) and it being transparent (or not) using the opacity property. A Link that is not visible is as if it didn’t exist. A Link that has opacity of zero (or really any number from zero to one) is present and participates in layout and reacts to mouse events.

Second, you should realize that there is a difference between state (such as a boolean property) that is in the model (such as on a link data object) and state that is in the diagram (such as the Link.visible or Link.opacity property). It depends on whether you want that state to be persistent or not. You might want to decide on the values when you generate the model or if you want that state to be saved for loading at a later time.

If you do not want to have the state in the model, just modify the Link.visible or Link.opacity properties directly. Something like:

myDiagram.commit(diag => {
  diag.links.each(l => {
    if (l.data.interlink) l.visible = !l.visible;
    // or l.opacity = l.opacity ? 0 : 1;
  });
});

If you do want the state to be in the model, have your link template include a binding on either the visible property or the opacity property:

  new go.Binding("visible")

OR

  new go.Binding("opacity", "visible", v => v ? 1 : 0)

These Bindings both assume that the “visible” property on the link data object will be a boolean.

Then you can modify the model dynamically as follows:

myDiagram.model.commit(m => {
  m.linkDataArray.forEach(d => {
    if (d.interlink) m.set(d, "visible", !d.visible);
  });
});

At the model level you don’t care about whether it is expressed by changing visible or opacity – that’s for the link template to decide.

By the way, I assume your link template will have a Binding on the Shape.stroke property of the path shape, something like:

$(go.Link,
  { curve: go.Link.Bezier },
  ... the Binding discussed above whose data source property is "visible" ...,
  $(go.Shape,
    { stroke: "red", strokeWidth: 4 },
    new go.Binding("stroke", "interlink", i => i ? "blue" : "red"))
)

Changing the opacity has achieved exatly what I need.

Is it possible to also add an animation to the opacity to make the links fade in/out.

Yes: GoJS Animation -- Northwoods Software

BTW, did you put the state in the model or are you directly modifying the Links in the Diagram?

The state is in the model.

I’ve taken the above and applied the same to hide certain nodes from view, however as the nodes still exist on the diagram they can still be clicked on and higlighted even though they’re invisible due to opacity zero.

Is there a way to also disable all events on the invisible nodes when their opacity is set to 0 ?

If you mean mouse/finger/stylus events, set or bind pickable to false.

So based on how i’m setting the visibility, how would I also make the invisible items not ‘pickable’ ?

myDiagram.model.commit(m => {
  m.linkDataArray.forEach(d => {
    if (d.interlink) m.set(d, "visible", !d.visible);
    if(!d.visible) // Do something here?
  });
});

new go.Binding("pickable", "visible") in your template

Ahh… perfect. That works great.