Try something like this custom layout:
<!DOCTYPE html>
<html>
<head>
<title>LayeredDigraphLayout spreading link labels</title>
<!-- Copyright 1998-2021 by Northwoods Software Corporation. -->
<meta name="description" content="A custom LayeredDigraphLayout that vertically spreads out link labels to reduce their overlaps">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/gojs"></script>
<script id="code">
function LabelSpreadingLDLayout() {
go.LayeredDigraphLayout.call(this);
}
go.Diagram.inherit(LabelSpreadingLDLayout, go.LayeredDigraphLayout);
// An override of LayeredDigraphLayout.commitLinks that between each layer assigns
// link label segmentFraction to alternate values to reduce the overlap of labels.
LabelSpreadingLDLayout.prototype.commitLinks = function() {
go.LayeredDigraphLayout.prototype.commitLinks.call(this);
// group all links by their "from" node/vertex layer
var allverts = new Map();
this.network.vertexes.each(v => {
if (!v.node) return;
let layer = allverts.get(v.layer);
if (!layer) { layer = []; allverts.set(v.layer, layer); }
layer.push(v);
});
for (const [layer, verts] of allverts) {
// for each group of links, sort by starting X
const links = [];
for (const v of verts) {
v.destinationEdges.each(e => {
if (e.link) links.push(e.link);
});
}
if (links.length > 1) {
if (this.direction === 90 || this.direction === 270) {
links.sort((a, b) => a.getPoint(0).x - b.getPoint(0).x);
} else {
links.sort((a, b) => a.getPoint(0).y - b.getPoint(0).y);
}
let i = 0;
for (const l of links) {
const lab = l.findMidLabel();
if (lab) {
lab.segmentFraction = (i%(4-1) + 1)/4;
i++;
}
}
}
}
}
// end LabelSpreadingLDLayout
function init() {
var $ = go.GraphObject.make;
// initialize main Diagram
myDiagram =
$(go.Diagram, "myDiagramDiv",
{
"linkingTool.archetypeLinkData": { label: "?%", code: 17 },
layout: $(LabelSpreadingLDLayout,
{ direction: 90, layerSpacing: 100, setsPortSpots: false }),
"undoManager.isEnabled": true
});
myDiagram.nodeTemplate =
$(go.Node, "Auto",
{ minSize: new go.Size(100, 50) },
$(go.Shape,
{
fill: "white", portId: "", cursor: "pointer",
fromLinkable: true, toLinkable: true,
fromLinkableDuplicates: true, toLinkableDuplicates: true
},
new go.Binding("figure", "shape"),
new go.Binding("fill", "shape", function(s) { return s === "Triangle" ? "lightgreen" : "lightblue"; })),
$(go.TextBlock,
new go.Binding("text", "key", function(k) { return "Entity " + k; }))
);
myDiagram.linkTemplate =
$(go.Link,
//{ fromEndSegmentLength: 0, toEndSegmentLength: 0 }, // more direct line style
{ fromSpot: go.Spot.TopBottomSides, toSpot: go.Spot.TopBottomSides }, // if direction === 90
//{ fromSpot: go.Spot.LeftRightSides, toSpot: go.Spot.LeftRightSides }, // if direction === 0
$(go.Shape),
$(go.TextBlock, { background: "white", segmentIndex: NaN, segmentFraction: 0.5 },
new go.Binding("text", "", function(d) { return (d.label || "") + "[Code " + (d.code || "") + "]"; }))
);
load();
}
// save a model to and load a model from Json text, displayed below the Diagram
function save() {
var str = myDiagram.model.toJson();
document.getElementById("mySavedModel").value = str;
}
function load() {
var str = document.getElementById("mySavedModel").value;
myDiagram.model = go.Model.fromJson(str);
}
</script>
</head>
<body onload="init()">
<div id="myDiagramDiv" style="width: 100%; height: 400px; border: solid 1px black"></div>
<button id="loadModel" onclick="load()">Load</button>
<button id="saveModel" onclick="save()">Save</button>
<textarea id="mySavedModel" style="width:100%;height:200px">
{ "class": "GraphLinksModel",
"linkKeyProperty": "key",
"nodeDataArray": [
{"key":1,"shape":"Triangle"},
{"key":2,"shape":"Triangle"},
{"key":3,"shape":"Triangle"},
{"key":4,"shape":"Rectangle"},
{"key":5,"shape":"Rectangle"},
{"key":6,"shape":"Rectangle"}
],
"linkDataArray": [
{"key":1,"from":1,"to":4,"label":"75%","code":1},
{"key":2,"from":2,"to":4,"label":"13%","code":2},
{"key":3,"from":3,"to":4,"label":"12%","code":3},
{"key":4,"from":1,"to":5,"label":"100%","code":4},
{"key":5,"from":1,"to":4,"label":"30%","code":5},
{"key":6,"from":2,"to":6,"label":"25%","code":6},
{"key":7,"from":3,"to":6,"label":"77%","code":7}
]}
</textarea>
</body>
</html>