This is my current makePort function -
function makePort(name, spot) {
return $(
go.Panel,
'Auto',
{
alignment: spot,
alignmentFocus: spot,
fromSpot: spot,
toSpot: spot,
cursor: 'pointer',
fromLinkable: true,
toLinkable: true,
opacity: 0,
},
new go.Binding('portId', 'key', key => `${name}::${key}`),
$(go.Shape, 'Rectangle', {
fill: lighten(common.white, 0.1),
stroke: null,
desiredSize: new go.Size(10, 10),
}),
$(go.Shape, 'XLine', {
name: 'x',
fill: null,
alignment: go.Spot.Center,
stroke: blueGrey[300],
desiredSize: new go.Size(5, 5),
})
);
}
The link template used here -
const linkTemplate = $(
go.Link,
{
routing: go.Link.Orthogonal,
curve: go.Link.JumpGap,
corner: 5,
reshapable: true,
resegmentable: true,
toShortLength: 10,
relinkableFrom: true,
relinkableTo: true,
selectable: true,
selectionAdornmentTemplate: linkSelectionAdornment,
},
bindings.linkPoints,
$(
go.Shape, // the link shape
{
cursor: 'pointer',
isPanelMain: true,
strokeWidth: 10,
stroke: 'transparent',
}
),
$(
go.Shape, // the link shape
{
isPanelMain: true,
strokeWidth: 2,
},
bindings.linkStroke,
bindings.strokeType
),
$(
go.Shape, // the arrow head
{
toArrow: 'standard',
stroke: null,
scale: 1.5,
fill: blue[700],
},
bindings.linkFill
),
$(
go.Panel, // panel for link label
'Auto',
{
segmentFraction: 0.5,
},
bindings.linkLabelVisible,
$(go.Shape, {
fill: common.white,
stroke: grey[200],
}),
$(
go.TextBlock, // label text
{
margin: 10,
editable: true,
},
bindings.label
)
),
{
toolTip: $(
// link tooltip
go.Adornment,
'Auto',
{
shadowVisible: true,
shadowColor: blueGrey[200],
isShadowed: true,
shadowBlur: 1,
shadowOffset: new go.Point(3, 3),
},
bindings.linkTooltipVisible,
$(go.Shape, 'RoundedRectangle', {
fill: common.white,
stroke: null,
}),
$(
go.TextBlock,
{
margin: new go.Margin(10),
shadowVisible: false,
},
bindings.text
)
),
}
);
The points bindings used above -
const parsePoints = pointsString => {
const points = JSON.parse(pointsString);
const list = new go.List();
for (let i = 0; i < points.length; i += 2) {
const x = parseFloat(points[i]);
const y = parseFloat(points[i + 1]);
list.add(new go.Point(x, y));
}
return list;
};
const stringifyPoints = pointsObj => {
const iterator = pointsObj.iterator;
const points = [];
while (iterator.next()) {
const point = iterator.value;
points.push(point.x);
points.push(point.y);
}
return JSON.stringify(points);
};
const bindings = {
get linkPoints() {
return new go.Binding('points', LINK_MODEL_ATTRS.POINTS, parsePoints).makeTwoWay(
stringifyPoints
);
}
};