Getting a Link from diagram

I tried several things and always I get a null, so I’m unable to get a Link object from diagram using findLinkForData method. This is a TypeScript code snippet:

static getLinkData(fromTo: string) : any {
        var json = JSON.parse(VisualDesigner.diagram.model.toJson());
        var linkArray: any[] = json['linkDataArray'];
        var link: any;
        for (var i = 0; i < linkArray.length; i++) {
            if (linkArray[i].from == fromTo || linkArray[i].to == fromTo) {
                link = linkArray[i];
                break;
            }
        }
        if (linkArray.length > 0) { // this is only for debug purpose
            console.log("link: " + link.from);
            console.log("link: " + VisualDesigner.diagram.findLinkForData(linkArray[0]));
        }
        return link;
    }

First output shows link’s from data as expected but second one returns null.

Model’s output:

{ "class": "go.GraphLinksModel",
  "nodeDataArray": [ 
{"key":101, "category":"root", "text":"ROOT1", "item":"mp_root", "taskType":0, "isGroup":true},
{"key":103, "category":"event", "text":"event1", "item":"mp_event", "taskType":0, "group":101, "loc":"-264 -189"},
{"key":108, "category":"share", "text":"event1", "item":"mp_share_new", "taskType":0, "gatewayType":1, "loc":"-352 62"}
 ],
  "linkDataArray": [ {"from":108, "to":103, "category":"share"} ]} 

What I have to do to get go.Link object using diagram.findLinkForData method?

First, why are you calling JSON.parse(...diagram.model.toJson())?

  1. That’s wildly inefficient.
  2. It’s why Diagram.findLinkForData isn’t working for you – the actual Link has its Link.data refer to a particular JavaScript object, but you’re asking it to look for a different one that happens to have the same properties and values.

Second, why are you declaring fromTo to be a string when your example link data object is { from: 108, to: 103, category: "share" }? Since you are using TypeScript, you could use the type go.Key, which is a union type definition.

If you really want to search for Links whose Part.data has particular properties, try using Diagram.findLinksByExample, http://gojs.net/latest/api/symbols/Diagram.html#findLinksByExample

Please tell me a better way to get diagram data instead of using JSON data of model. I’m open to improve my knowledge of GoJS library. I suspected that problem was because I’m using linkDataArray from JSON data. I noticed that key is number but library always interpret things properly (probably because this is a Javascript) so I left it as string when noticed that as a fact. If you think I will run into problems because of that I will change that immediately or I just need to convert it to go.Key to be sure it will work in the right way.

I will try with Diagram.findLinksByExample, thanks for suggestion.

Lazy thing I guess. Now when you confirmed my suspicions I did what I mostly hate to do. To use casts. Now this way it works, but I still hope there is a nicer way to get linkDataArray.

var model: go.GraphLinksModel = <go.GraphLinksModel>VisualDesigner.diagram.model;
var linkArray: any[] = model.linkDataArray;

Or maybe that is because of Typescript. In plain Javascript diagram.model.linkDataArray should work anyway.

I’m glad you got it working. I assume that’s without using Diagram.findLinksByExample?

Yeah your assumption is right.

But I must ask for something else. Is there a way to get shape object from link like I can get it from node? Seems that link does not have findObject method.

All Panels have the Panel.findObject method, and all Nodes and Links are Parts, which inherit from Panel. You’ll need to give a name to the Shape that you care about.

But are you sure that you want to be calling findObject? Data binding might be more appropriate. http://gojs.net/latest/intro/usingModels.html followed by http://gojs.net/latest/intro/dataBinding.html.

While waited for your answer I was played with data binding. But didn’t make it yet to work. Is this info in console normal? GraphLinksModel.setDataProperty is modifying a GraphObject, "Link#5488([object Object])" Is that really your intent?

This is my link template

private shareLinkTemplate(): go.Link {
return $$(go.Link,
    {
        contextMenu:
        $$(go.Adornment, "Vertical"),
        routing: go.Link.AvoidsNodes, curve: go.Link.JumpOver, corner: 10,
        //fromSpot: go.Spot.TopSide, toSpot: go.Spot.TopSide,
        reshapable: true, relinkableFrom: true, relinkableTo: true, toEndSegmentLength: 20
    },
    new go.Binding("points").makeTwoWay(),
    $$(go.Shape, {name: "Line", stroke: "green", strokeWidth: 1, strokeDashArray: [6, 3] }, 
        new go.Binding("strokeWidth").makeTwoWay(),
        new go.Binding("stroke", "color")
    ),
    $$(go.TextBlock, { // this is a Link label
        name: "Label", editable: true, text: "label", segmentOffset: new go.Point(-10, -10), visible: false
    },
        new go.Binding("text", "text").makeTwoWay(),
        new go.Binding("visible", "visible").makeTwoWay())
);

}

And this is how I trying to change from code colour of link line

        var link = VisualDesigner.diagram.findLinkForData(linkArray[i]);
        if (link !== null) {
            VisualDesigner.diagram.model.setDataProperty(link, "color", "red");
        }

But no change of colour for me just info in console: GraphLinksModel.setDataProperty is modifying a GraphObject, "Link#5488([object Object])"...

Yes, you are passing a Link to that Model.setDataProperty method, whereas it actually takes model data: setDataProperty(link.data, "color", "red")

That’s why the names of the various Model methods are a bit more verbose than they could be – to emphasize that they work with data objects, not Diagram Parts.