Find all overlapped links under the cursor

The figure below shows 4 boxes in two columns and the boxes between columns are fully connected. When hovering over certain link, the link should be highlighted. I am using a yellow triangle to indicate the location of the cursor.

Unfortunately, the link from Box1 to Box3 has the lowest zOrder and therefore it can never be highlighted, as illustrated below.

I am wondering if the following design idea is possible using GoJS: when a cursor is hovering over multiple links that are overlapped, detect all the covered links at the cursor’s location so that a row of colored dots can be displayed for users to click to highlight the corresponding link.

Screen Shot 2022-01-28 at 10.38.24 PM

The example here is the over-simplified version of the issue that we are facing. So, the fundamental question is if there is a way for GoJS to find all the links (or even parts) at certain document position? Any idea will be really appreciated!

Below is the HTML + JS code to illustrate the issue mentioned in this post. Thanks for your time!

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div
      id="myDiagramDiv"
      style="border: solid 1px black; width: 100%; height: 700px"
    ></div>
    <script src="../../release/go-debug.js"></script>
    <script>
      function init() {
        const $ = go.GraphObject.make;
        myDiagram = $(go.Diagram, "myDiagramDiv", {
          layout: $(go.LayeredDigraphLayout, {
            layerSpacing: 80,
          }),
        });

        myDiagram.nodeTemplate = $(
          go.Node,
          "Spot",
          new go.Binding("location", "loc", go.Point.parse),
          $(go.Shape, "RoundedRectangle", {
            fill: "white",
            width: 100,
            height: 50,
            portId: "",
            fromLinkable: true,
            toLinkable: true,
            cursor: "pointer",
          }),
          $(
            go.TextBlock, // the text label
            new go.Binding("text", "key"),
            {
              verticalAlignment: go.Spot.Center,
              textAlign: "center",
            },
          ),
        );

        myDiagram.linkTemplate = $(
          go.Link,
          {
            routing: go.Link.AvoidsNodes,
            corner: 10,
            mouseEnter: function (e, link) {
              link.findObject("HOVER").stroke = "rgba(0, 0, 0, 0.3)";
            },
            mouseLeave: function (e, link) {
              link.findObject("HOVER").stroke = "transparent";
            },
          },
          $(go.Shape, {
            isPanelMain: true,
            name: "HOVER",
            strokeWidth: 16,
            stroke: "transparent",
          }),
          $(go.Shape, { isPanelMain: true, strokeWidth: 2 }),
          $(go.Shape, { toArrow: "Standard", stroke: null }),
        );

        const nodeDataArray = [
          {
            key: "Box1",
          },
          {
            key: "Box2",
          },
          {
            key: "Box3",
          },
          {
            key: "Box4",
          },
        ];

        const linkDataArray = [
          {
            from: "Box1",
            to: "Box3",
          },
          {
            from: "Box1",
            to: "Box4",
          },
          {
            from: "Box2",
            to: "Box3",
          },
          {
            from: "Box2",
            to: "Box4",
          },
        ];

        const model = new go.GraphLinksModel();
        model.nodeDataArray = nodeDataArray;
        model.linkDataArray = linkDataArray;
        myDiagram.model = model;
      }

      window.addEventListener("DOMContentLoaded", init);
    </script>
  </body>
</html>

Yes, call: Diagram.findPartsAt Diagram | GoJS API

More generally, you could call: Diagram.findObjectsAt Diagram | GoJS API which is less convenient but more flexible.

Another common strategy for the situation you describe is to have repeated clicks select successive choices. An example is in Tree Map But I think what you propose is better. Would you have mouseOver each dot highlight the corresponding Link?

Fantastic! Thank you, Walter! I will investigate the TreeMap code. Have a great weekend!

We are thinking that clicking on each dot will highlight the corresponding link. By default, since the link with the highest zOrder is highlighted, its dot should be selected.