In this image as visible that link is bend I want straight link and in some how any of data this red link is also bend and pls provide me that how to correct this , I am provide you code below
<!DOCTYPE html>
<html lang="en">
<body>
<script src="https://unpkg.com/[email protected]"></script>
<div id="allSampleContent" class="p-4 w-full">
<script src="./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', {
allowCopy: false,
initialContentAlignment: go.Spot.LeftCenter,
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: 40, //** should be bigger than the default value of 25
columnSpacing: 20, //** should be smaller than the default value of 25
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;
if (horiz) {
offset.y -= this.columnSpacing * 3 / 2;
} else {
offset.x -= this.columnSpacing * 3 / 2;
}
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);
}
//** Added this shift for all lanes
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: false,
selectable: false,
selectionChanged: (part) => {
console.log(part)
}
},
new go.Binding('location', 'loc', go.Point.parse),
go.Panel.Horizontal,
{
portId: '',
fromSpot: go.Spot.RightCenter, // coming out from right side
toSpot: go.Spot.LeftCenter, // g
click: (e, node) => {
console.log('ddd', e, node)
}
},
$(go.Panel,
go.Panel.Auto,
{
},
$(go.Shape, 'RoundedRectangle',
{
fill: 'white',
minSize: new go.Size(150, 100),
desiredSize: new go.Size(240, 140),
strokeWidth: 1,
},
{ cursor: 'pointer' }, // indicate that linking may start here
new go.Binding('fill', 'actionType', actionType => getNodeColor(actionType)),
new go.Binding('stroke', 'actionType', actionType => getNodeStrokeColor(actionType))
),
$(go.Panel,
'Horizontal',
$(go.TextBlock,
{
maxLines: 3,
overflow: go.TextBlock.OverflowEllipsis,
alignment: go.Spot.Center,
font: '15px Inter, sans-serif',
maxSize: new go.Size(140, NaN), // Restrict the width
margin: 3,
cursor: "pointer",
},
{ fromLinkable: false, toLinkable: false }, // don't start drawing a link from the text
new go.Binding('text', 'text'),
),
),
),
{ // 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('EndConditionStep', $(go.Node, "Auto",
{
selectionAdorned: false,
movable: false,
selectable: false,
selectionChanged: (part) => {
console.log(part)
}
},
// new go.Binding('location', 'loc', go.Point.parse),
go.Panel.Horizontal,
{
portId: '',
fromSpot: go.Spot.RightCenter, // coming out from right side
toSpot: go.Spot.LeftCenter, // g
click: (e, node) => {
console.log('ddd', e, node)
}
},
$(go.Panel,
go.Panel.Auto,
{
},
$(go.Shape, 'Diamond',
{
fill: 'white',
minSize: new go.Size(150, 100),
desiredSize: new go.Size(150, 100),
strokeWidth: 1,
},
{ cursor: 'pointer' }, // indicate that linking may start here
new go.Binding('fill', 'actionType', actionType => getNodeColor(actionType)),
new go.Binding('stroke', 'actionType', actionType => getNodeStrokeColor(actionType))
),
$(go.Panel,
'Horizontal',
$(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(140, NaN), // Restrict the width
margin: 3,
cursor: "pointer",
},
{ fromLinkable: false, toLinkable: false }, // don't start drawing a link from the text
new go.Binding('text', 'text'),
),
),
),
{ // 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",
{
selectionAdorned: false,
movable: false,
selectable: false,
selectionChanged: (part) => {
console.log(part)
}
},
new go.Binding('location', 'loc', go.Point.parse),
go.Panel.Horizontal,
{
portId: '',
fromSpot: go.Spot.RightCenter, // coming out from right side
toSpot: go.Spot.LeftCenter, // g
click: (e, node) => {
console.log('ddd', e, node)
}
},
$(go.Panel,
go.Panel.Auto,
{
},
$(go.Shape, 'Diamond',
{
fill: 'white',
minSize: new go.Size(150, 100),
desiredSize: new go.Size(150, 100),
strokeWidth: 1,
},
{ cursor: 'pointer' }, // indicate that linking may start here
),
$(go.Panel,
'Horizontal',
$(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(140, NaN), // Restrict the width
margin: 3,
cursor: "pointer",
},
{ fromLinkable: false, toLinkable: false }, // don't start drawing a link from the text
new go.Binding('text', 'text'),
),
),
),
{ // 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.linkTemplate = $(go.Link, // the whole link panel
{
routing: go.Link.AvoidsNodes,
curve: go.Curve.JumpOver,
corner: 0,
fromEndSegmentLength: 30, //** to force links to go farther around
toEndSegmentLength: 30
},
$(go.Shape, // the link shape
{ strokeWidth: 1.5, stroke: '#116173' },
new go.Binding('stroke', 'text', (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", "text", (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', 'text', (textnew) => {
if (textnew !== '' && textnew !== 'YES') {
return '#FF0404';
} else if (textnew === 'YES') {
return '#00B66A';
}
return '#116173'; // default color
}),
new go.Binding('fill', 'text', (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.Orientation.Upright
},
new go.Binding("text", "text").makeTwoWay()
)
),
new go.Binding("fromSpot", "text", (textNew) => textNew == '' ? go.Spot.Right : (textNew == "YES" ? go.Spot.Right : go.Spot.Top)).makeTwoWay(),
new go.Binding("toSpot", "text", (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, }),
),
);
partitionBy('d');
}
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": "D",
"text": "D",
"category": "BusinessStep",
"group": "a",
},
{
"key": "E",
"text": "E",
"category": "ConditionStep",
"group": "a",
},
{
"key": "F",
"text": "F",
"category": "ConditionStep",
"group": "a",
},
{
"key": "G",
"text": "G",
"category": "EndConditionStep",
"group": "a",
},
{
"key": "H",
"text": "H",
"category": "EndConditionStep",
"group": "a",
},
{
"key": "I",
"text": "I",
"category": "BusinessStep",
"group": "hp",
},
{
"key": "J",
"text": "J",
"category": "BusinessStep",
"group": "a",
},
{
"key": "K",
"text": "K",
"category": "BusinessStep",
"group": "a",
},
{
"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",
"text": ""
},
{
"from": "H",
"to": "end_node",
"text": ""
},
{
"from": "A",
"to": "J",
"text": ""
},
{
"from": "J",
"to": "E",
"text": ""
},
{
"from": "E",
"to": "K",
"text": "YES"
},
{
"from": "E",
"to": "F",
"text": "NO"
},
{
"from": "K",
"to": "F",
"text": ""
},
{
"from": "F",
"to": "I",
"text": ""
},
{
"from": "I",
"to": "G",
"text": ""
},
{
"from": "G",
"to": "D",
"text": "YES"
},
{
"from": "D",
"to": "H",
"text": ""
},
{
"from": "G",
"to": "H",
"text": "NO"
},
]
// 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 category="radio" name="A" onclick="partitionBy('c')" id="conferenceButton">
<label for="conferenceButton">Conferences</label><br>
<input category="radio" name="A" onclick="partitionBy('d')" id="divisionButton" checked="">
<label for="divisionButton">Divisions</label><br>
</div>
</body>
</html>
And in swimlanelayout comparevertex function these changes and rest same swimlanelayout
compareVertexes(v, w) {
let laneV = this.findLane(v);
if (laneV === null) laneV = '';
let laneW = this.findLane(w);
if (laneW === null) laneW = '';
if (laneV < laneW) return 1;
if (laneV > laneW) return -1;
// comment this two line if link wants from bottom to bottom connect
if (v.node === null && w.node !== null) return -1;
if (v.node !== null && w.node === null) return 1;
if (v.column < w.column) return -1;
if (v.column > w.column) return 1;
return 0;
}