Port adjust dynamicaly according to link data property available

<!DOCTYPE html>
<html lang="en">

<body>
    <script src="https://unpkg.com/[email protected]"></script>

    <div id="allSampleContent" class="p-4 w-full">




        <script src="https://unpkg.com/[email protected]/dist/extensions/SwimLaneLayout.js"></script>
        <script id="code">
            var DIRECTION = 0; // used to customize the layout and the templates, only upon first initialization

            function init() {
                if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this

                var $ = go.GraphObject.make; // for conciseness in defining templates

                myDiagram = new go.Diagram('myDiagramDiv', {
                    // automatically scale the diagram to fit the viewport's size
                    initialAutoScale: go.AutoScale.Uniform,
                    // disable user copying of parts
                    allowCopy: false,
                    initialContentAlignment: go.Spot.LeftCenter,
                    // position all of the nodes and route all of the links
                    layout: $(SwimLaneLayout, {
                        laneProperty: 'group', // needs to know how to assign vertexes/nodes into lanes/groups
                        direction: DIRECTION, // Group template also depends on DIRECTION
                        setsPortSpots: false,
                        layerSpacing: 20,
                        columnSpacing: 5,
                        commitLayers: function (layerRects, offset) {
                            // method override requires function, not =>
                            if (layerRects.length === 0) return;

                            var horiz = this.direction === 0 || this.direction === 180;
                            var forwards = this.direction === 0 || this.direction === 90;

                            var rect = layerRects[forwards ? layerRects.length - 1 : 0];
                            var totallength = horiz ? rect.right : rect.bottom;

                            for (var i = 0; i < this.laneNames.length; i++) {
                                var lane = this.laneNames[i];
                                // assume lane names do not conflict with node names
                                var group = this.diagram.findNodeForKey(lane);
                                if (group === null) {
                                    this.diagram.model.addNodeData({ key: lane, isGroup: true });
                                    group = this.diagram.findNodeForKey(lane);
                                }
                                if (horiz) {
                                    group.location = new go.Point(-this.layerSpacing / 2, this.lanePositions.get(lane) * this.columnSpacing + offset.y);
                                } else {
                                    group.location = new go.Point(this.lanePositions.get(lane) * this.columnSpacing + offset.x, -this.layerSpacing / 2);
                                }
                                var ph = group.findObject('PLACEHOLDER'); // won't be a go.Placeholder, but just a regular Shape
                                if (ph === null) ph = group;
                                if (horiz) {
                                    ph.desiredSize = new go.Size(totallength, (this.laneBreadths.get(lane) * this.columnSpacing));
                                } else {
                                    ph.desiredSize = new go.Size(this.laneBreadths.get(lane) * this.columnSpacing, (totallength));
                                }
                            }
                        },
                    }),
                });

                myDiagram.nodeTemplate = $(go.Node, "Auto",
                    {
                        selectionAdorned: false,
                        movable: true,
                        selectionChanged: (part) => {
                            console.log(part)
                            //part.findNodesOutOf().each(n => n.fill = '#116173');
                            // const shape = part.elt(0);
                            // shape.fill = '#116173';
                        }
                    },
                    new go.Binding('location', 'loc', go.Point.parse),
                    go.Panel.Horizontal,
                    {
                        portId: '',
                        // fromLinkable: true, 
                        // toLinkable: true,
                        fromSpot: go.Spot.RightCenter,  // coming out from right side
                        toSpot: go.Spot.LeftCenter,   // g
                        click: (e, node) => {
                            //this.showHideNode(node)
                            console.log('ddd', e, node)
                        }
                    },
                    $(go.Panel,
                        go.Panel.Auto,
                        {
                            // click:(e, node) =>{
                            //   console.log('ddd', e, node)
                            // }
                        },
                        $(go.Shape, 'RoundedRectangle',
                            {
                                fill: 'white',
                                minSize: new go.Size(150, 100),
                                desiredSize: new go.Size(150, 100),
                                strokeWidth: 1,
                                margin: new go.Margin(40, 0),
                                //stretch: go.GraphObject.Horizontal,
                            },
                            { cursor: 'pointer' }, // indicate that linking may start here
                            new go.Binding('stroke', 'color'),
                            //new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),

                        ),
                        $(go.Panel,
                            'Horizontal',

                            $(go.TextBlock,
                                {
                                    margin: 2,
                                    stroke: '#4c525e',
                                    cursor: 'pointer',
                                    // stretch: go.GraphObject.Horizontal, 
                                    verticalAlignment: go.Spot.LeftCenter,
                                    textAlign: 'left',
                                    overflow: go.TextBlock.OverflowEllipsis,
                                    wrap: go.TextBlock.None,
                                    desiredSize: new go.Size(140, 25),
                                },
                                { fromLinkable: false, toLinkable: false }, // don't start drawing a link from the text
                                new go.Binding('text', 'text'),
                                new go.Binding('stroke', 'color')
                            ),

                        ),
                    ),
                    { // Tooltip for showing full text on hover
                        toolTip: $(go.Adornment, "Auto",
                            $(go.Shape, { fill: "#ffffff" }),
                            $(go.TextBlock, { margin: 4 },
                                new go.Binding("text", "text"))
                        )
                    },
                );

                // replace the default Node template in the nodeTemplateMap
                // myDiagram.nodeTemplate = $(go.Node,
                //   'Vertical', // the whole node panel
                //   {
                //     // when the DIRECTION is vertical, use the whole Node as the port
                //     fromSpot: go.Spot.TopBottomSides,
                //     toSpot: go.Spot.TopBottomSides,
                //   },
                //   $(go.TextBlock, // the text label
                //     new go.Binding('text', 'key')
                //   ),
                //   // $(go.Picture, // the icon showing the logo
                //   //   // You should set the desiredSize (or width and height)
                //   //   // whenever you know what size the Picture should be.
                //   //   {
                //   //     desiredSize: new go.Size(50, 50),
                //   //     // when the DIRECTION is horizontal, use this icon as the port
                //   //     portId: DIRECTION === 0 || DIRECTION === 180 ? '' : null,
                //   //     fromSpot: go.Spot.LeftRightSides,
                //   //     toSpot: go.Spot.LeftRightSides,
                //   //   },
                //   //   new go.Binding('source', 'key', convertKeyImage)
                //   // )
                // );

                myDiagram.nodeTemplateMap.add(
                    'ConditionStep',
                    $(go.Node,
                        'Auto',
                        { selectable: false },
                        new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
                        $(go.Panel, "Vertical",
                            // { margin: new go.Margin(40, 0) },
                            // { defaultAlignment: go.Spot.Left },
                            $(go.Panel, "Auto",
                                // { defaultAlignment: go.Spot.Top, defaultStretch: go.GraphObject.Vertical, },
                                $(go.Shape, 'Diamond', {
                                    strokeWidth: .5,
                                    // fill: "#F4B9B8",
                                    fill: "#FFFFC2",
                                    stroke: '#F79489',
                                    desiredSize: new go.Size(80, 80),
                                    // fromLinkable: false,
                                    // toLinkable: false,
                                    // fromLinkableDuplicates: false,
                                    // toLinkableDuplicates: false,
                                    // fromSpot: go.Spot.Right,
                                    // toSpot: go.Spot.Left,
                                    // portId: "",
                                    // fromSpot: go.Spot.AllSides,
                                    // toSpot: go.Spot.AllSides,
                                    cursor: "pointer",
                                    // minSize: new go.Size(150, 100),
                                    // desiredSize: new go.Size(150, 100),
                                },

                                ),
                                $(go.TextBlock, new go.Binding('text', 'text', (text) => {
                                    console.log(text);
                                    return text = "IF"
                                }),
                                ),
                                {
                                    toolTip: $(go.Adornment, "Auto",
                                        $(go.Shape, { fill: "#FFFFCC" }),
                                        $(go.TextBlock, { margin: 4 },
                                            new go.Binding("text", "key"))
                                    )
                                },

                            ),
                            // $(go.Panel, "Auto", { alignment: go.Spot.Center, desiredSize: new go.Size(180, 40), },
                            $(go.Panel, "Auto", { alignment: go.Spot.Center },
                                $(go.TextBlock,
                                    {
                                        maxLines: 3,
                                        overflow: go.TextBlock.OverflowEllipsis,
                                        // wrap: go.TextBlock.None,
                                        alignment: go.Spot.Center,
                                        font: '15px Inter, sans-serif',
                                        maxSize: new go.Size(200, NaN), // Restrict the width
                                        margin: 3,
                                        cursor: "pointer",
                                    },
                                    new go.Binding('text', 'key')),
                            )
                        ),
                    ),
                );

                // replace the default Link template in the linkTemplateMap
                myDiagram.linkTemplate = $(go.Link, // the whole link panel
                    { routing: go.Routing.AvoidsNodes, corner: 10 },
                    $(go.Shape, // the link shape
                        { strokeWidth: 1.5 }
                    ),
                    $(go.Shape, // the arrowhead
                        { toArrow: 'Standard', stroke: null }
                    )
                );

                myDiagram.groupTemplate = // assumes SwimLaneLayout.direction === 0
                    $(go.Group,
                        DIRECTION === 0 || DIRECTION === 180 ? 'Horizontal' : 'Vertical',
                        {
                            layerName: 'Background', // always behind all regular nodes and links
                            movable: false, // user cannot move or copy any lanes
                            copyable: false,
                            locationObjectName: 'PLACEHOLDER', // this object will be sized and located by SwimLaneLayout
                            layout: null, // no lane lays out its member nodes
                            avoidable: false, // don't affect any AvoidsNodes link routes,
                        },
                        $(go.TextBlock, { font: 'bold 12px sans-serif', angle: DIRECTION === 0 || DIRECTION === 180 ? 270 : 0 }, new go.Binding('text', 'text')),
                        $(go.Panel,
                            'Auto',
                            $(go.Shape, { fill: 'transparent', stroke: 'orange' }),
                            $(go.Shape, { name: 'PLACEHOLDER', fill: null, stroke: null, strokeWidth: 0, }),
                            // $(go.TextBlock, { font: 'bold 12pt sans-serif'}, new go.Binding('text', 'text')),
                        ),
                        // $(go.TextBlock, { font: 'bold 12pt sans-serif', angle: DIRECTION === 0 || DIRECTION === 180 ? 90 : 0 }, new go.Binding('text', 'text'))
                    );

                partitionBy('d');
            }

            // the array of node data describing each team, each division, and each conference

            const newDataSet =
                [
                    {
                        "key": "start_node",
                        "text": "Start",
                        "category": "start_node",
                        "group": "cp",
                    },
                    {
                        "key": "end_node",
                        "text": "End",
                        "category": "end_node",
                        "group": "hp",
                    },
                    {
                        "key": "A",
                        "text": "A",
                        "category": "BusinessStep",
                        "group": "hp",
                    },
                    {
                        "key": "B",
                        "text": "B",
                        "category": "BusinessStep",
                        "group": "cp",
                    },
                    {
                        "key": "C",
                        "text": "C",
                        "category": "BusinessStep",
                        "group": "hp",
                    },
                    {
                        "key": "D",
                        "text": "D",
                        "category": "ConditionStep",
                        "group": "a",
                    },
                    {
                        "key": "E",
                        "text": "E",
                        "category": "BusinessStep",
                        "group": "hp",
                    },
                    {
                        "key": "cp",
                        "text": "cp",
                        "category": "Lane",
                        "isGroup": true
                    },
                    {
                        "key": "a",
                        "text": "a",
                        "category": "Lane",
                        "isGroup": true
                    },
                    {
                        "key": "hp",
                        "text": "hp",
                        "category": "Lane",
                        "isGroup": true
                    }
                ];

            const newLinkData =
                [
                    {
                        "from": "start_node",
                        "to": "A"
                    },
                    {
                        "from": "E",
                        "to": "end_node"
                    },
                    {
                        "from": "A",
                        "to": "B"
                    },
                    {
                        "from": "B",
                        "to": "D",
                    },
                    {
                        "from": "D",
                        "to": "E",
                        "textnew":"No"
                    },
                    {
                        "from": "D",
                        "to": "C",
                        "textnew":"Yes"
                    },
                    {
                        "from": "C",
                        "to": "E"
                    }
                ]




            // the array of link data objects: the relationships between the nodes

            function partitionBy(a) {
                // create the model and assign it to the Diagram
                var model = new go.GraphLinksModel();
                // depending on how we are partitioning the graph, each node belongs either
                // to a conference group or to a division group
                model.nodeGroupKey = a === 'c' ? 'conf' : 'group';
                model.nodeDataArray = newDataSet;
                model.linkDataArray = newLinkData;
                // each node's lane information is the same as the group information
                myDiagram.layout.laneProperty = model.nodeGroupKey;
                // optionally, specify the order of known lane names, without setting laneComparer
                //myDiagram.layout.laneNames = a === 'c' ? ['AFC', 'NFC'] : ['AFCE', 'AFCN', 'AFCS', 'AFCW', 'NFCE', 'NFCN', 'NFCS', 'NFCW'];
                myDiagram.model = model;
            }
            window.addEventListener('DOMContentLoaded', init);
        </script>

        <div id="sample">
            <!-- <p><b>Beat Paths</b>: The 2007 NFL Season, divided by conference or by division</p> -->
            <div id="myDiagramDiv"
                style="border: 1px solid gray; margin: 10px; height: 100vh; position: relative; -webkit-tap-highlight-color: rgba(255, 255, 255, 0);">
                <canvas tabindex="0" width="1226" height="698"
                    style="position: absolute; top: 0px; left: 0px; z-index: 2; user-select: none; touch-action: none; width: 1226px; height: 698px;"></canvas>
                <div style="position: absolute; overflow: auto; width: 1226px; height: 698px; z-index: 1;">
                    <div style="position: absolute; width: 1px; height: 1px;"></div>
                </div>
            </div>
            <input type="radio" name="A" onclick="partitionBy('c')" id="conferenceButton">
            <label for="conferenceButton">Conferences</label><br>
            <input type="radio" name="A" onclick="partitionBy('d')" id="divisionButton" checked="">
            <label for="divisionButton">Divisions</label><br>
        </div>
</body>

</html>

This is my code in this ConditionStep is there and in this condiitonstep in link data one textnew property is there that is having yes and no and in this I want that in condition step means diamond box shape if textnew Yes is there then fromspot for link is from right and to spot is left

and if textnew is No then fromSpot is from bottom and tospot is also bottom

Means I am accordingly adjusts port dynamically

And in this you also visible that port is not connect in diamond corner do that also that from spot and tospot connect on diamond corner

I am provide you code Pls Execute this code and give the solution of my issue

Uncomment this line which declares the “Diamond” Shape to be the Node.port for the Node:

        portId: "",

This is not working

My requirement is If in link textnew is present then according to text either Yes or No port changes

If yes come then fromspot is right and tospot is left

If No come then fromspot is bottom and tospot is also bottom if in same lane and in different lane then fromspot is bottom and tospot is left

const newLinkData =
[
{
“from”: “start_node”,
“to”: “A”
},
{
“from”: “E”,
“to”: “end_node”
},
{
“from”: “A”,
“to”: “B”
},
{
“from”: “B”,
“to”: “D”,
},
{
“from”: “B”,
“to”: “H”,
},
{
“from”: “H”,
“to”: “D”,
},
{
“from”: “D”,
“to”: “E”,
“textnew”:“No”
},
{
“from”: “D”,
“to”: “C”,
“textnew”:“Yes”
},
{
“from”: “C”,
“to”: “E”
}
]

In this linkdata that textnew property is there . Example : “textnew”:“Yes”

OK, then on the Link template you can add a Binding to “fromSpot” that determines the correct Spot to use.

Yes,

If in link textnew is present then according to text either Yes or No port changes

If yes come then fromspot is right and tospot is left

If No come then fromspot is bottom and tospot is also bottom if in same lane and in different lane then fromspot is bottom and tospot is left

Good – I’m glad you got it implemented.

Please implement from your side I am try to implement but not work , Please implement in given code

We are not your contractors – you are responsible for your own app’s code.

What have you done so far, and how is it not working the way that you want?

when using portid that fromspot and tospot is not updated dynamically I am using that

new go.Binding(“fromSpot”, “textNew”, textNew => textNew == ‘Yes’ ? ‘Top’ : ‘Bottom’).makeTwoWay(),
new go.Binding(“toSpot”, “textNew”, textNew => textNew == ‘Yes’ ? ‘Top’ : ‘Bottom’).makeTwoWay()

in link template

this.myDiagram.linkTemplate = $(go.Link, // the whole link panel
  { routing: go.Link.AvoidsNodes, corner: 10 , fromSpot: go.Spot.AllSides,
    toSpot: go.Spot.AllSides, },
  $(go.Shape, // the link shape
    { strokeWidth: 1.5, stroke: 'lightblue' }
  ),
  $(go.Shape, // the arrowhead
    { toArrow: 'Standard', stroke: 'lightblue' }
  ),
  new go.Binding("fromSpot", "textNew", textNew => textNew == 'Yes' ? 'Top' : 'Bottom').makeTwoWay(),
  new go.Binding("toSpot", "textNew", textNew => textNew == 'Yes' ? 'Top' : 'Bottom').makeTwoWay()
)

The types of the GraphObject.fromSpot and .toSpot properties are Spot, not string, so you need to return either go.Spot.Top or go.Spot.Bottom.

If you use go-debug.js instead of go.js, you would receive an error message in the console about that error.

Thanks , this working but facing some issues like links are folded not straight

in this above image if connect to c and in this if and c links are not straight ,

myDiagram.linkTemplate = $(go.Link, // the whole link panel
{
routing: go.Routing.AvoidsNodes, curve: go.Curve.JumpOver, corner: 10
},
$(go.Shape, // the link shape
{ strokeWidth: 1.5, stroke: ‘lightblue’ }
),
$(go.Shape, // the arrowhead
{ toArrow: ‘Standard’, stroke: ‘lightblue’ }
),
new go.Binding(“fromSpot”, “textnew”, (textNew) => textNew == ‘’ ? go.Spot.Right : (textNew == “Yes” ? go.Spot.Right:go.Spot.Bottom)).makeTwoWay(),
new go.Binding(“toSpot”, “textnew”, (textNew) => textNew == ‘’ ? go.Spot.Left : (textNew == “Yes” ? go.Spot.Left:go.Spot.Bottom)).makeTwoWay()
)

So you want that “If” Node to be a bit lower, yes?

Depending on the layout, this might not help, but normally if you want the positioning of a node not to depend on extraneous objects like the label underneath the “Diamond” Shape of your “If” Node, I would give that Shape a GraphObject.name and then set Node.locationObjectName to that name.

Question 1 : - I am using SwimLaneLayout

and in link template this is use
{
routing: go.Link.AvoidsNodes,
curve: go.Curve.JumpOver,
corner: 0,

                },

By using this

In this I am using one red link and in this fromspot and tospot is position Top

But that link is spot is top but link directlt not go straight this link come from top then come down and again go up and conect top

I want that link fromspot is top and go straight link and tospot connect top directly not take longest path , shortest path take for link connect.

Question 2 : -

part 1
If I am using this code
$(go.Panel, “Auto”,
new go.Binding(“visible”, “textnew”, (textnew) => textnew == “” ? false : true).makeTwoWay(),
$(go.Shape, “RoundedRectangle”, // the rounded rectangle shape
{ fill: “#E0FFF2”, stroke: “#00B66A”, strokeWidth: 1.5 },
{ segmentIndex: 0 },

                        new go.Binding('stroke', 'textnew', (textnew) => {
                            if (textnew !== '' && textnew !== 'Yes') {
                                return '#FF0404';
                            } else if (textnew === 'Yes') {
                                return '#00B66A';
                            }
                            return '#116173'; // default color
                        }),
                        new go.Binding('fill', 'textnew', (textnew) => {
                            if (textnew !== '' && textnew !== 'Yes') {
                                return '#FFE4E4';
                            } else if (textnew === 'Yes') {
                                return '#E0FFF2';
                            }
                            return '#116173'; // default color
                        })
                    ),

                    $(go.TextBlock,
                        {
                            font: '9pt Figtree, sans-serif',
                            margin: 3,
                            editable: true,
                            segmentIndex: 0,
                            segmentOrientation: go.Link.Upright
                        },
                        new go.Binding("text", "textnew").makeTwoWay()
                    )
                ),

part 2
and if using this code
$(go.TextBlock,
{
segmentIndex: 0, segmentOffset: new go.Point(NaN, NaN),
segmentOrientation: go.Orientation.Upright
},
new go.Binding(“text”, “textnew”).makeTwoWay()
),

I want posiiton as part 2 but panel shape want to use as part1 pls provide solution as that poisiotn take as part 2 and shape use as part1

I’ll look into question 1 later.

For question 2, the GraphObject.segment… properties control how the link label is positioned and oriented. Just set those properties on the label object in your link template. Please read Link Labels | GoJS

Already used in given code that segement but due to use panel that position not working if I am remove panel then that working , but want shape and textblock both so panel is mandatory to use so how I handle that

But you haven’t set the other segment… properties on the panel.

Thanks this working now

now question 1 left

Could you please provide your Diagram definition, all of your current template definitions, and the model so that I can reproduce problem 1?

<!DOCTYPE html>
<html lang="en">

<body>
    <script src="https://unpkg.com/[email protected]"></script>

    <div id="allSampleContent" class="p-4 w-full">




        <script src="https://unpkg.com/[email protected]/dist/extensions/SwimLaneLayout.js"></script>
        <script id="code">
            var DIRECTION = 0; // used to customize the layout and the templates, only upon first initialization

            function init() {
                if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this

                var $ = go.GraphObject.make; // for conciseness in defining templates

                myDiagram = new go.Diagram('myDiagramDiv', {
                    // automatically scale the diagram to fit the viewport's size
                    initialAutoScale: go.AutoScale.Uniform,
                    // disable user copying of parts
                    allowCopy: false,
                    initialContentAlignment: go.Spot.LeftCenter,
                    // position all of the nodes and route all of the links
                    layout: $(SwimLaneLayout, {
                        laneProperty: 'group', // needs to know how to assign vertexes/nodes into lanes/groups
                        direction: DIRECTION, // Group template also depends on DIRECTION
                        setsPortSpots: false,
                        layerSpacing: 20,
                        // layeringOption: go.LayeredDigraphLayout.LayerOptimalLinkLength,
                        linkSpacing: 10,
                        // packOption: go.LayeredDigraphLayout.PackAll,
                        // columnSpacing: 15,
                        commitLayers: function (layerRects, offset) {
                            // method override requires function, not =>
                            if (layerRects.length === 0) return;

                            var horiz = this.direction === 0 || this.direction === 180;
                            var forwards = this.direction === 0 || this.direction === 90;

                            var rect = layerRects[forwards ? layerRects.length - 1 : 0];
                            var totallength = horiz ? rect.right : rect.bottom;

                            for (var i = 0; i < this.laneNames.length; i++) {
                                var lane = this.laneNames[i];
                                // assume lane names do not conflict with node names
                                var group = this.diagram.findNodeForKey(lane);
                                if (group === null) {
                                    this.diagram.model.addNodeData({ key: lane, isGroup: true });
                                    group = this.diagram.findNodeForKey(lane);
                                }
                                if (horiz) {
                                    group.location = new go.Point(-this.layerSpacing / 2, this.lanePositions.get(lane) * this.columnSpacing + offset.y);
                                } else {
                                    group.location = new go.Point(this.lanePositions.get(lane) * this.columnSpacing + offset.x, -this.layerSpacing / 2);
                                }
                                var ph = group.findObject('PLACEHOLDER'); // won't be a go.Placeholder, but just a regular Shape
                                if (ph === null) ph = group;
                                if (horiz) {
                                    ph.desiredSize = new go.Size(totallength, (this.laneBreadths.get(lane) * this.columnSpacing));
                                } else {
                                    ph.desiredSize = new go.Size(this.laneBreadths.get(lane) * this.columnSpacing, (totallength));
                                }
                            }
                        },
                    }),
                });

                myDiagram.nodeTemplate = $(go.Node, "Auto",
                    {
                        selectionAdorned: false,
                        movable: true,
                        selectionChanged: (part) => {
                            console.log(part)
                            //part.findNodesOutOf().each(n => n.fill = '#116173');
                            // const shape = part.elt(0);
                            // shape.fill = '#116173';
                        }
                    },
                    new go.Binding('location', 'loc', go.Point.parse),
                    go.Panel.Horizontal,
                    {
                        portId: '',
                        // fromLinkable: true, 
                        // toLinkable: true,
                        fromSpot: go.Spot.RightCenter,  // coming out from right side
                        toSpot: go.Spot.LeftCenter,   // g
                        click: (e, node) => {
                            //this.showHideNode(node)
                            console.log('ddd', e, node)
                        }
                    },
                    $(go.Panel,
                        go.Panel.Auto,
                        {
                            // click:(e, node) =>{
                            //   console.log('ddd', e, node)
                            // }
                        },
                        $(go.Shape, 'RoundedRectangle',
                            {
                                fill: 'white',
                                minSize: new go.Size(150, 100),
                                desiredSize: new go.Size(150, 100),
                                strokeWidth: 1,
                                margin: new go.Margin(40, 0),
                                //stretch: go.GraphObject.Horizontal,
                            },
                            { cursor: 'pointer' }, // indicate that linking may start here
                            new go.Binding('stroke', 'color'),
                            //new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),

                        ),
                        $(go.Panel,
                            'Horizontal',

                            $(go.TextBlock,
                                {
                                    margin: 2,
                                    stroke: '#4c525e',
                                    cursor: 'pointer',
                                    // stretch: go.GraphObject.Horizontal, 
                                    verticalAlignment: go.Spot.LeftCenter,
                                    textAlign: 'left',
                                    overflow: go.TextBlock.OverflowEllipsis,
                                    wrap: go.TextBlock.None,
                                    desiredSize: new go.Size(140, 25),
                                },
                                { fromLinkable: false, toLinkable: false }, // don't start drawing a link from the text
                                new go.Binding('text', 'text'),
                                new go.Binding('stroke', 'color')
                            ),

                        ),
                    ),
                    { // Tooltip for showing full text on hover
                        toolTip: $(go.Adornment, "Auto",
                            $(go.Shape, { fill: "#ffffff" }),
                            $(go.TextBlock, { margin: 4 },
                                new go.Binding("text", "text"))
                        )
                    },
                );





                myDiagram.nodeTemplateMap.add(
                    'ConditionStep',
                    $(go.Node,
                        'Auto',
                        { selectable: false, locationObjectName: "DiamondShape" },
                        // new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
                        $(go.Panel, "Vertical",
                            // { margin: new go.Margin(40, 0) },
                            // { defaultAlignment: go.Spot.Left },
                            $(go.Panel, "Auto",
                                // { defaultAlignment: go.Spot.Top, defaultStretch: go.GraphObject.Vertical, },
                                $(go.Shape, 'Diamond', {
                                    name: "DiamondShape",
                                    strokeWidth: .5,
                                    margin: new go.Margin(50, 0, 0, 0),
                                    // fill: "#F4B9B8",
                                    fill: "#FFFFC2",
                                    stroke: '#F79489',
                                    desiredSize: new go.Size(80, 80),
                                    // fromLinkable: false,
                                    // toLinkable: false,
                                    // fromLinkableDuplicates: false,
                                    // toLinkableDuplicates: false,
                                    // fromSpot: go.Spot.Right,
                                    // toSpot: go.Spot.Left,
                                    portId: "",
                                    // fromSpot: go.Spot.AllSides,
                                    // toSpot: go.Spot.AllSides,
                                    cursor: "pointer",
                                    // minSize: new go.Size(150, 100),
                                    // desiredSize: new go.Size(150, 100),
                                }, new go.Binding('margin', 'text', (text) => {
                                    console.log(text);
                                    console.log(text.length);
                                    if (text.length < 25) {
                                        return new go.Margin(20, 0, 0, 0)
                                    }
                                    if (text.length > 25 && text.length < 50) {
                                        return new go.Margin(40, 0, 0, 0)
                                    }
                                    if (text.length > 50) {
                                        return new go.Margin(50, 0, 0, 0)
                                    }
                                })

                                ),
                                $(go.Panel, "Horizontal",
                                    $(go.Panel, "Horizontal",
                                        // { alignment: go.Spot.Right },
                                        $(go.TextBlock,
                                            new go.Binding('text', 'text', (text) => {
                                                console.log(text);
                                                return "IF";
                                            })
                                        ),
                                    ),

                                    $(go.Panel, "Horizontal",
                                        // { alignment: go.Spot.Right },
                                        $(go.Panel, "Spot",
                                            { width: 45, height: 30 },
                                            { margin: new go.Margin(7, -25, 0, 5) },
                                            $(go.Shape, "Circle",
                                                // { alignment: go.Spot.Right },
                                                { fill: "white", stroke: "#C3BC00", desiredSize: new go.Size(20, 20) }
                                            ),
                                            $(go.TextBlock,
                                                { textAlign: "center" },
                                                // { verticalAlignment: go.Spot.Center },
                                                new go.Binding('text', 'text', (text) => {
                                                    console.log(text);
                                                    return "4";
                                                })
                                            )
                                        )
                                    )
                                ),

                                {
                                    toolTip: $(go.Adornment, "Auto",
                                        $(go.Shape, { fill: "#FFFFCC" }),
                                        $(go.TextBlock, { margin: 4 },
                                            new go.Binding("text", "text"))
                                    )
                                },
                            ),
                            // $(go.Panel, "Auto", { alignment: go.Spot.Center, desiredSize: new go.Size(180, 40), },
                            $(go.Panel, "Auto", { alignment: go.Spot.Center },
                                { margin: new go.Margin(10, 0, 0, 0) },
                                $(go.TextBlock,
                                    {
                                        maxLines: 3,
                                        overflow: go.TextBlock.OverflowEllipsis,
                                        // wrap: go.TextBlock.None,
                                        alignment: go.Spot.Center,
                                        font: '15px Inter, sans-serif',
                                        maxSize: new go.Size(200, NaN), // Restrict the width
                                        margin: 3,
                                        cursor: "pointer",
                                    },
                                    new go.Binding('text', 'key')),
                            )
                        ),
                    ),
                );








                myDiagram.linkTemplate = $(go.Link, // the whole link panel
                    {
                        routing: go.Link.AvoidsNodes,
                        curve: go.Curve.JumpOver,
                        corner: 0,

                    },
                    $(go.Shape, // the link shape
                        { strokeWidth: 1.5, stroke: '#116173' },
                        new go.Binding('stroke', 'textnew', (textnew) => {
                            if (textnew !== '' && textnew !== 'Yes') {
                                return '#FF0404';
                            } else if (textnew === 'Yes') {
                                return '#00B66A';
                            }
                            return '#116173'; // default color
                        })
                    ),
                    $(go.Shape, // the arrowhead
                        { toArrow: 'Standard', stroke: 'lightblue' }
                    ),





                    $(go.Panel, "Auto",
                    {
                        segmentIndex: 0, segmentOffset: new go.Point(NaN, NaN),
                            segmentOrientation: go.Orientation.Upright
                    },
                        new go.Binding("visible", "textnew", (textnew) => textnew == "" ? false : true).makeTwoWay(),
                        $(go.Shape, "RoundedRectangle", // the rounded rectangle shape
                            { fill: "#E0FFF2", stroke: "#00B66A", strokeWidth: 1.5 },
                            { segmentIndex: 0 },

                            new go.Binding('stroke', 'textnew', (textnew) => {
                                if (textnew !== '' && textnew !== 'Yes') {
                                    return '#FF0404';
                                } else if (textnew === 'Yes') {
                                    return '#00B66A';
                                }
                                return '#116173'; // default color
                            }),
                            new go.Binding('fill', 'textnew', (textnew) => {
                                if (textnew !== '' && textnew !== 'Yes') {
                                    return '#FFE4E4';
                                } else if (textnew === 'Yes') {
                                    return '#E0FFF2';
                                }
                                return '#116173'; // default color
                            })
                        ),

                        $(go.TextBlock,
                            {
                                font: '9pt Figtree, sans-serif',
                                margin: 3,
                                editable: true,
                                segmentIndex: 0,
                                segmentOrientation: go.Link.Upright
                            },
                            new go.Binding("text", "textnew").makeTwoWay()
                        )
                    ),



                    new go.Binding("fromSpot", "textnew", (textnew) => textnew === '' ? go.Spot.Right : (textnew === "Yes" ? go.Spot.Right : go.Spot.Top)).makeTwoWay(),
                    new go.Binding("toSpot", "textnew", (textnew) => textnew === '' ? go.Spot.Left : (textnew === "Yes" ? go.Spot.Left : go.Spot.Top)).makeTwoWay()
                );




                myDiagram.groupTemplate = // assumes SwimLaneLayout.direction === 0
                    $(go.Group,
                        DIRECTION === 0 || DIRECTION === 180 ? 'Horizontal' : 'Vertical',
                        {
                            layerName: 'Background', // always behind all regular nodes and links
                            movable: false, // user cannot move or copy any lanes
                            copyable: false,
                            locationObjectName: 'PLACEHOLDER', // this object will be sized and located by SwimLaneLayout
                            layout: null, // no lane lays out its member nodes
                            avoidable: false, // don't affect any AvoidsNodes link routes,
                        },
                        $(go.TextBlock, { font: 'bold 12px sans-serif', angle: DIRECTION === 0 || DIRECTION === 180 ? 270 : 0 }, new go.Binding('text', 'text')),
                        $(go.Panel,
                            'Auto',
                            $(go.Shape, { fill: 'transparent', stroke: 'orange' }),
                            $(go.Shape, { name: 'PLACEHOLDER', fill: null, stroke: null, strokeWidth: 0, }),
                            // $(go.TextBlock, { font: 'bold 12pt sans-serif'}, new go.Binding('text', 'text')),
                        ),
                        // $(go.TextBlock, { font: 'bold 12pt sans-serif', angle: DIRECTION === 0 || DIRECTION === 180 ? 90 : 0 }, new go.Binding('text', 'text'))
                    );

                partitionBy('d');
            }

            // the array of node data describing each team, each division, and each conference

            const newDataSet =
                [
                    {
                        "key": "start_node",
                        "text": "Start",
                        "category": "start_node",
                        "group": "cp",
                    },
                    {
                        "key": "end_node",
                        "text": "End",
                        "category": "end_node",
                        "group": "hp",
                    },
                    {
                        "key": "A",
                        "text": "A",
                        "category": "BusinessStep",
                        "group": "hp",
                    },
                    {
                        "key": "B",
                        "text": "B",
                        "category": "BusinessStep",
                        "group": "a",
                    },
                    {
                        "key": "H",
                        "text": "H",
                        "category": "BusinessStep",
                        "group": "a",
                    },
                    {
                        "key": "C",
                        "text": "C",
                        "category": "BusinessStep",
                        "group": "a",
                    },
                    {
                        "key": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghg",
                        "text": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghg",
                        "category": "ConditionStep",
                        "group": "a",
                    },
                    {
                        "key": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgD",
                        "text": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgD",
                        "category": "ConditionStep",
                        "group": "a",
                    },
                    {
                        "key": "E",
                        "text": "E",
                        "category": "BusinessStep",
                        "group": "hp",
                    },
                    {
                        "key": "cp",
                        "text": "cp",
                        "category": "Lane",
                        "isGroup": true
                    },
                    {
                        "key": "a",
                        "text": "a",
                        "category": "Lane",
                        "isGroup": true
                    },
                    {
                        "key": "hp",
                        "text": "hp",
                        "category": "Lane",
                        "isGroup": true
                    }
                ];

            const newLinkData =
                [
                    {
                        "from": "start_node",
                        "to": "A",
                        "textnew": ""
                    },
                    {
                        "from": "E",
                        "to": "end_node",
                        "textnew": ""
                    },
                    {
                        "from": "A",
                        "to": "B",
                        "textnew": ""
                    },
                    {
                        "from": "B",
                        "to": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghg",
                        "textnew": ""
                    },
                    {
                        "from": "B",
                        "to": "H",
                        "textnew": ""
                    },
                    {
                        "from": "H",
                        "to": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghg",
                        "textnew": ""
                    },
                    {
                        "from": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghg",
                        "to": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgD",
                        "textnew": "No"
                    },
                    {
                        "from": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghg",
                        "to": "C",
                        "textnew": "Yes"
                    },
                    {
                        "from": "C",
                        "to": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgD",
                        "textnew": ""
                    },
                    {
                        "from": "DhghgDhghgDhghgDhghgDhghgDhghgDhghgDhghgD",
                        "to": "E",
                        "textnew": ""
                    }
                ]

            function getNodeStrokeColor(subcategory) {
                console.log(subcategory);
                if (subcategory == 'Yes') {
                    return 'red'
                }
                // return subcategory == 'Yes' ? 'red'
                // return this.subcategoryColorsStroke[subcategory] || '#17E09A'; // Default color if subcategory is not defined
            }



            // the array of link data objects: the relationships between the nodes

            function partitionBy(a) {
                // create the model and assign it to the Diagram
                var model = new go.GraphLinksModel();
                // depending on how we are partitioning the graph, each node belongs either
                // to a conference group or to a division group
                model.nodeGroupKey = a === 'c' ? 'conf' : 'group';
                model.nodeDataArray = newDataSet;
                model.linkDataArray = newLinkData;
                // each node's lane information is the same as the group information
                myDiagram.layout.laneProperty = model.nodeGroupKey;
                // optionally, specify the order of known lane names, without setting laneComparer
                //myDiagram.layout.laneNames = a === 'c' ? ['AFC', 'NFC'] : ['AFCE', 'AFCN', 'AFCS', 'AFCW', 'NFCE', 'NFCN', 'NFCS', 'NFCW'];
                myDiagram.model = model;
            }
            window.addEventListener('DOMContentLoaded', init);
        </script>

        <div id="sample">
            <!-- <p><b>Beat Paths</b>: The 2007 NFL Season, divided by conference or by division</p> -->
            <div id="myDiagramDiv"
                style="border: 1px solid gray; margin: 10px; height: 100vh; position: relative; -webkit-tap-highlight-color: rgba(255, 255, 255, 0);">
                <canvas tabindex="0" width="1226" height="698"
                    style="position: absolute; top: 0px; left: 0px; z-index: 2; user-select: none; touch-action: none; width: 1226px; height: 698px;"></canvas>
                <div style="position: absolute; overflow: auto; width: 1226px; height: 698px; z-index: 1;">
                    <div style="position: absolute; width: 1px; height: 1px;"></div>
                </div>
            </div>
            <input type="radio" name="A" onclick="partitionBy('c')" id="conferenceButton">
            <label for="conferenceButton">Conferences</label><br>
            <input type="radio" name="A" onclick="partitionBy('d')" id="divisionButton" checked="">
            <label for="divisionButton">Divisions</label><br>
        </div>
</body>

</html>

Thanks. I’m not sure why that red link is being routed below node C, but I can look into it.

Is everything else working well?