<!DOCTYPE html>
<html>
<head>
<title>Buttons Shown on Hover over Link</title>
<!-- Copyright 1998-2025 by Northwoods Software Corporation. -->
</head>
<body>
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
<textarea id="mySavedModel" style="width:100%;height:250px"></textarea>
<script src="https://cdn.jsdelivr.net/npm/gojs/release/go-debug.js"></script>
<script id="code">
const myDiagram =
new go.Diagram("myDiagramDiv", {
hoverDelay: 200, // controls how long to wait motionless (msec) before showing Adornment
"undoManager.isEnabled": true,
"ModelChanged": e => { // just for demonstration purposes,
if (e.isTransactionFinished) { // show the model data in the page's TextArea
document.getElementById("mySavedModel").textContent = e.model.toJson();
}
}
});
// the node template doesn't matter for this sample
myDiagram.nodeTemplate =
new go.Node("Auto")
.bind("location", "loc", go.Point.parse)
.add(
new go.Shape({
fill: "white",
portId: "", fromSpot: go.Spot.AllSides, toSpot: go.Spot.AllSides
})
.bind("fill", "color"),
new go.TextBlock({ margin: 8 })
.bind("text")
);
// This is adapted from the samples/hoverButtons.html sample.
// This Adornment is shown by the mouseHover event handler:
const linkHoverAdornment = new go.Adornment('Horizontal', {
locationSpot: go.Spot.Center,
locationObjectName: "CENTER",
// hide the Adornment when the mouse leaves it
mouseLeave: (e, obj) => {
var ad = obj.part;
ad.adornedPart.removeAdornment('mouseHover');
},
background: "transparent",
isActionable: true, // needed because this is in a temporary Layer
click: (e, obj) => {
var link = obj.part.adornedPart;
link.diagram.select(link);
}
})
.add(
go.GraphObject.build('Button', {
alignment: go.Spot.Left, alignmentFocus: go.Spot.Right,
click: (e, obj) => alert('Hi!')
})
.add(new go.TextBlock('Hi!')),
new go.Shape({
name: "CENTER",
width: 12, height: 12,
fill: null, strokeWidth: 0
}),
go.GraphObject.build('Button', {
alignment: go.Spot.Right, alignmentFocus: go.Spot.Left,
click: (e, obj) => alert('Bye')
})
.add(new go.TextBlock('Bye'))
);
myDiagram.linkTemplate =
new go.Link({
routing: go.Routing.AvoidsNodes,
// show the Adornment when a mouseHover event occurs
mouseHover: (e, obj) => {
var link = obj.part;
linkHoverAdornment.adornedObject = link;
linkHoverAdornment.location = e.documentPoint;
link.addAdornment('mouseHover', linkHoverAdornment);
}
})
.add(
// a wide transparent background Shape makes it easier to interact with
new go.Shape({ isPanelMain: true, stroke: "transparent", strokeWidth: 5 }),
new go.Shape({ isPanelMain: true }), // this is what users see
new go.Shape({ toArrow: "OpenTriangle" }),
new go.TextBlock({
segmentOrientation: go.Orientation.Upright,
background: "whitesmoke"
})
.bind("text")
);
myDiagram.model = new go.GraphLinksModel(
[
{ key: 1, text: "Alpha", color: "lightblue", loc: "0 100" },
{ key: 2, text: "Beta", color: "orange", loc: "300 0" },
],
[
{ from: 1, to: 2, text: "label 1" },
]);
</script>
</body>
</html>