Shapes on links moved procentual by resegmenting

Hello,

We draw a shape on a link. This link is resegmentable. If we make a subdivision of a link, then the shape is been slipped to an offset. We think that there is an offset been set in code behind, but can not figure out why and where. The position of the points (start and end) remain the same even after the move.

The aim is that the shape is always drawn on the link, even if points are added or removed.

Can you give us a hint on this?

LinkTemplate:

go.GraphObject.make(go.Link,
        {
            name: "LINK",
            selectable: true,
            relinkableFrom: true,
            relinkableTo: true,
            reshapable: true,
            resegmentable: true,
            adjusting: go.Link.End,
            fromEndSegmentLength: 45,
            toEndSegmentLength: 45,
            movable: false,
            selectionChanged: function(part) {
                if (part.data.from !== undefined && part.data.to !== undefined && !part.isSelected) {
                    part.diagram.model.setDataProperty(part.data, 'visible', false);
                }
                else {
                    part.diagram.model.setDataProperty(part.data, 'visible', true);
                }
            }
        },
        new go.Binding("points", "points"),
        go.GraphObject.make(go.Shape,
            {
                name: "FLOW",
                fill: "green",
                stroke: "transparent",
                pickable: true,
                click: function(e, obj) {
                    obj.part.isSelected = true;
                },
            },
            new go.Binding("segmentOffset", "flowSegmentOffset", function(targetprop, sourceprop) {
                return new go.Point(0, 0);
            }).makeTwoWay(),
            new go.Binding("geometryString", "points", function(targetprop, sourceprop) {
                if (sourceprop.part.data.from !== undefined && sourceprop.part.data.to !== undefined) {
                    return self.calculatePath(targetprop.n);
                }
                return "";
            }).ofObject()
        ),
        go.GraphObject.make(go.Shape, {
            name: "AA",
            isPanelMain: true,
        },
            new go.Binding("visible", "visible")
        ),
        go.GraphObject.make(go.Shape,
            {
                toArrow: "Standard"
            },
            new go.Binding("visible", "visible")
        ),
        go.GraphObject.make(go.Panel, "Auto",
            {
                cursor: "pointer"
            },
            go.GraphObject.make(go.TextBlock, "transition",  // the label
                {
                    textAlign: "center",
                    font: "9pt sans-serif",
                    stroke: "black",
                    editable: false
                },
                new go.Binding("text", "text").makeTwoWay()
            ),
            // The GraphObject.segmentOffset property is what the LinkLabelDraggingTool modifies.
            // This TwoWay binding saves any changes to the same named property on the link data.
            new go.Binding("segmentOffset", "segmentOffset", go.Point.parse).makeTwoWay(go.Point.stringify)
        )

    )

The calculation of the geometry for link paths is quite different than for link labels. The reason is that the link paths depend on the Link.points which are in document coordinates, whereas labels can have whatever geometry they want but are positioned relative to the link route within the “Link” Panel that is each Link.

I assume you haven’t yet looked at examples such as the Tapered Links sample, Tapered Links, and the MultiArrow sample, Multi-Arrow Links. Note that they both depend on overrides of Link.makeGeometry, which simplifies and generalizes the process of making a geometry from the link points. This approach is much better than trying to get the positioning correct using Bindings.

But have you tried just using a thick stroke, and not bothering with custom geometries? For example,

    myDiagram.linkTemplate =
      $(go.Link,
        {
          relinkableFrom: true, relinkableTo: true, reshapable: true, resegmentable: true,
          fromSpot: go.Spot.Right, fromEndSegmentLength: 24, fromShortLength: 1,
          toSpot: go.Spot.Left, toEndSegmentLength: 24, toShortLength: 16
        },
        $(go.Shape, { strokeWidth: 17, stroke: "green" }),
        $(go.Shape, { fromArrow: "Triangle", scale: 2, stroke: null, fill: "white" }),
        $(go.Shape, { toArrow: "Triangle", scale: 2, stroke: null, fill: "green" })
      );

produces:

Hey,

thanks for your fast replay. I’ve looked at the samples, but i think that we need a solution with independent shapes for each flow. One thing i didn’t say, is that we can have a Link with two or more flows in different colors and with an independent width.

So we need a link which one is a black line and around this we can have shapes in different colors.

Are you sure you don’t want to use multiple Links? Such as:

If you are sure you only want to have a single Link going between the two nodes in these examples, I believe that it can be done but would require some non-trivial programming.

But it would be easier to change the model so that there are two (or three or more) links for each abstract link that you have. Or keep the model the same but create two or three Links for each link data object in the model.

Hi Walter thanks for your replays.

Just for your information, we are working together with ifu Hamburg, you probably know their product e!Sankey. Actually We are trying to develop a mobile-eSankey-application based on GoJS.

From your last replays we decided to override the makeGeometry function like you suggested. This workes so far. Now we want to brush each figure of the geometry in different colors. Is that possible and how?

Another question… we used in e!Sankey (based on GoDiagram) the paint-methode to create the flows… is there a function like that in GoJS?

thanks so far

Sorry, but no – to use a different brush for the stroke or the fill, you have to use a different Shape. But the Shape.geometry would be shared by all Shapes that are GraphObject.isPanelMain, so that would not help you.

We do not support “paint” methods, because that would prevent us from rendering SVG.

So it looks like my most recent suggestion, using multiple Links, is necessary. You can still adapt the custom Link.makeGeometry code to work differently on different Links.