How to place one node on top of another node

i have two node templates - Node1 and Node2 as seen in the image below.

On hovering over Node2 I want to the Node1 to appear on top of Node 2 as seen in the image.

Even when Node 2 is selected, the hover should still work.

Its ok if Node1 is not a go.Node and just a Shape inside Node2.

Also, Node1 is clickable.

In your mouseHover event handler, GraphObject | GoJS API, would it be OK to just find and move Node1 to where you want it to be?

Would you want to also implement a mouseLeave event handler to move Node1 back to where it had been? But the event handler will need to check whether the mouse is leaving Node2 to go into Node1 and not move Node1 then. The mouseLeave event handler on Node1 would need to do the same check when leaving Node1 but going into Node2.

the default state would be just seeing Node2. When i hover over or rather on mouseEnter of Node2, Node1 appears at the RightCenter of the Node2, and on mouseLeave of Node2, Node1 disappears.

Also, when i am inside Node1, Node2’s mouseLeave shouldn’t get triggered else i wont be able to click within Node1.

Your mouseLeave event handler should look at the next argument to decide whether or not to move Node1 back to where it was originally. Same goes for the mouseLeave event handler on Node1, when going back to Node2 (except presumably you do not want to move Node1).

No, I don’t want to move Node1. By default, Node1 is not present in the diagram. Only Node2 is present.

Node1 only appears on mouse enter of Node2 and disappears on mouse leave of Node2.

Also, how can I place a a go.Node object over another go.Node object. In this case, Node1 appearing over Node2 on mouseEnter.

Can u share a sample code as I didn’t understand what you meant by next argument.

Well, that’s what I understood from looking at your screenshots.

Do these actually need to be Nodes? Will there be Links connecting them?
If not, maybe you could just use plain Parts or Adornments.
In particular, I was thinking that upon mouseEnter you could add an Adornment to Node2, and remove that Adornment upon mouseLeave.
Examine the Hover Buttons sample: Buttons that show on Hover

Node1 need not be a Node. Following the Hover Button sample, when i try to replace Button with go.Shape, “Circle”, i get this error:

A GraphObject can only be added to a Panel, not to: Shape(Circle)#181
at C (http://localhost:3000/static/js/bundle.js:56245:11)
at Tl (http://localhost:3000/static/js/bundle.js:73782:50)
at Ul (http://localhost:3000/static/js/bundle.js:73773:156)

Sample Code :

export const nodeHoverAdornment = $(
  go.Adornment,
  "Spot",
  {
    name: "NODEHOVERADORNMENT",
  },
  $(go.Placeholder, {
    isActionable: true, // needed because this is in a temporary Layer
  }),
  $(
    go.Shape,
    "Circle",
    {
      width: 30,
      height: 30,
      background: "transparent",
    },
    { click: (e, obj) => alert("Bye") },
    $(go.TextBlock, "Bye")
  )
);

This is the mouseEnter and mouseLeave on Node2:

mouseEnter: (e, node) => {
      console.log("mouse enter");
      const mainNodeObject = node.part.findObject("MAINNODE");
      nodeHoverAdornment.adornedObject = mainNodeObject;
      node.part.addAdornment("mouseEnter", nodeHoverAdornment);
    },
    mouseLeave: (e, node) => {
      node.part.removeAdornment("mouseEnter");
    },

Also, when i am inside the Adorned Button mouseLeave of Node2 triggers which give a flickering effect.

Yes, your template is trying to add a TextBlock to a Shape. One can only add elements to a Panel.

Also, you need to move that isActionable setting to the GraphObject where the click event handler is. This setting is only needed in Adornments.

modified the nodeHoverAdornment as per ur suggestion

export const nodeHoverAdornment = $(
  go.Adornment,
  "Spot",
  {},
  $(go.Placeholder, {}),
  $(
    go.Shape,
    "Circle",
    {
      name: "NODEHOVERADORNMENT",
      width: 30,
      height: 30,
      fill: "green",
    },
    { click: (e, obj) => alert("Bye"), isActionable: true }
  )
);

However, the mouseLeave and mouseEnter events gets triggered continuously when my mouse pointer is inside adornment.
How to prevent this from happening?

When you show the Adornment, is the mouse point contained by the Adornment? If so, the mouse is leaving whatever it was in and entering the Adornment (or some GraphObject within it). Don’t remove the Adornment if the mouse is in the Adornment!

In the Hover Buttons sample, note that there’s no mouseLeave event handler on or in the Node.

Right, in the Hover Buttons example the adornment will only be remove when i explicitly go inside the AdornedButton and leave from there.

However, the scenario that i need is that the AdornedObject should stay until i am either in the Node or in the AdornedObject. If I am not in one of the two objects, I want the adornment to be removed.

PS. While I am in the Node, I may or may not move my cursor inside the Adorned Object. Hence, the remove Adornment was written in the Node.

Hope I am able to explain the problem

OK, so don’t remove the Adornment if the mouse is in either the Node or in the Adornment.

Note that mouseLeave GraphObject | GoJS API (and mouseEnter, for that matter) are functions that take three arguments – you may be interested in the third argument!

Ahh, thank you for the hint. Got it working with the third parameter. :)