Show the child graph content to the parent graph issue

Hi, I used a tree left side. I want to show the child graph content to the parent graph. I am saving the location of each node of the child graph. For the parent graph saving position of the subgroup(not the content). But I want to show (auto-positioning) the content of the subgroup that I have saved in the child. I don’t use any Layout. I have used placed holder in the group template.

Please help me.

Sub Graph 1

Sub Graph 2

Parent Graph

Did you start with the Regrouping TreeView demo?

That has a tree on the left side that shows the group/member relationships of the main diagram that is on the right side.

One difference from what I understand you are describing, is that the Regrouping TreeView sample has an automatic layout that is each Group.layout, whereas you want users to manually position each node, including nested groups. But that’s OK – just don’t set Group.layout in your group template.

Presumably the node template(s) in the main diagram have a TwoWay Binding on the Node.location property. The node template(s) in the tree view do not need any location binding. (If they have such a binding, the results of the binding will be overridden/ignored by the TreeLayout in the tree view diagram, so why bother having a binding there?)

1 Like

Thanks for your reply. I didn’t start with the regrouping demo. Because my child diagram content is different(Drag and drop). I don’t use any layout in the group or diagram. My problem is I saved the position of the node and link to the child. diagram. Now I want to show this child diagram as a part of the parent diagram. if possible you may help me for calculating the relative position of the node and link for the parent diagram.

Oh, so your question has nothing to do with the tree view, and only that the coordinates that you have saved for each node and link route are relative to the containing group, not to the whole document.

But if your link route points are relative to the group, which coordinate system have you used when a link connects nodes in two different groups?

Thanks, My Current requirement is each node and link are contained in a group and a parent graph is a group containing multiple groups or nodes.

Why do you have link routes saved in your database?

You can convert local (group) coordinates to global (document) coordinates by summing up the node location and each of the containing group locations.

Do you also need to save local coordinates when the user moves a node?

When the user moves a group, the saved locations of its member nodes are not changed. Is that correct? What happens when the user moves a node to be partly or completely outside of the bounds of a group? If it is permitted, does the group automatically changes size? If so, what should happen when the group’s location changes due to that change in size? Do all of the member nodes get their locations modified too?

Link Route need to save because there is a lot of node and link in a group, and maybe they can conflict for this reason link want to save. but it’s not important if no conflict.

When the user moves a group, the saved locations of its member nodes are not changed.? yes

What happens when the user moves a node to be partly or completely outside of the bounds of a group? The user won’t move outside of the group.

all time I saved the node and group sizes.

So the size of each group is not determined by the positions of its member nodes?

Yes, In the child graph, I can resize it, But in the parent graph, Group can move and resize. but group resize in parent graph is not mandatory.

This is incomplete, but it’s what I could make for you during the weekend:

<!DOCTYPE html>
  <title>Relative location for Group members</title>
  <!-- Copyright 1998-2022 by Northwoods Software Corporation. -->
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <script src=""></script>
  <script id="code">
  function init() {
    var $ = go.GraphObject.make;  // for conciseness in defining templates

    myDiagram =
      $(go.Diagram, "myDiagramDiv",  // create a Diagram for the DIV HTML element
          // allow double-click in background to create a new node
          "clickCreatingTool.archetypeNodeData": { text: "Node", color: "white" },

          // allow Ctrl-G to call groupSelection()
          "commandHandler.archetypeGroupData": { text: "Group", isGroup: true, color: "blue" },

          "ModelChanged": function(e) {
            if (e.isTransactionFinished) {
              document.getElementById("savedModel").textContent = myDiagram.model.toJson();

          // enable undo & redo
          "undoManager.isEnabled": true

    // Define the appearance and behavior for Nodes:

    // Assume the data.loc property has a relative location for the node compared to its containing group.
    // (If there is no group data, it is the location in document coordinates.)
    // toLocation should not depend on any Node.location because they might not have been initialized yet.
    function toLocation(data) {
      var loc = go.Point.parse(data.loc);
      if ( !== undefined) {
        var groupdata = myDiagram.model.findNodeDataForKey(;
        if (groupdata) {
      return loc;

    // fromLocation just saves in data.loc either the absolute location if there's no containing Group,
    // or the relative location with its containing Group.
    function fromLocation(location, data) {
      if ( !== undefined) {
        var group = myDiagram.findNodeForKey(;
        if (group) {
          var loc = location.copy().subtract(group.location);
          data.loc = loc.x.toFixed(2) + " " + loc.y.toFixed(2);  //go.Point.stringify(loc);
      } else {
        data.loc = go.Point.stringify(location);

    // this is a Part.dragComputation function for limiting where a Node may be dragged
    function stayInGroup(part, pt, gridpt) {
      // don't constrain top-level nodes
      const grp = part.containingGroup;
      if (grp === null) return pt;
      // try to stay within the background Shape of the Group
      const back = grp.resizeObject;
      if (back === null) return pt;
      // allow dragging a Node out of a Group if the Shift key is down
      if (part.diagram.lastInput.shift) return pt;
      const r = back.getDocumentBounds();
      const b = part.actualBounds;
      const loc = part.location;
      // now limit the location appropriately
      const x = Math.max(r.x + 10, Math.min(pt.x, r.right - 10 - b.width - 1)) + (loc.x - b.x);
      const y = Math.max(r.y + 10, Math.min(pt.y, r.bottom - 10 - b.height - 1)) + (loc.y - b.y);
      return new go.Point(x, y);

    // These nodes have text surrounded by a rounded rectangle
    // whose fill color is bound to the node data.
    // The user can drag a node by dragging its TextBlock label.
    // Dragging from the Shape will start drawing a new link.
    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        new go.Binding("location", "", toLocation).makeTwoWay(fromLocation),
        { dragComputation: stayInGroup },
        $(go.Shape, "RoundedRectangle",
            fill: "white", // the default fill, if there is no data-binding
            portId: "", cursor: "pointer",  // the Shape is the port, not the whole Node
            // allow all kinds of links from and to this port
            fromLinkable: true, fromLinkableSelfNode: true, fromLinkableDuplicates: true,
            toLinkable: true, toLinkableSelfNode: true, toLinkableDuplicates: true
          new go.Binding("fill", "color")),
            font: "bold 14px sans-serif",
            stroke: '#333',
            margin: 6,  // make some extra space for the shape around the text
            isMultiline: false,  // don't allow newlines in text
            editable: true  // allow in-place editing by user
          new go.Binding("text", "text").makeTwoWay())  // the label shows the node data's text

    // The link shape and arrowhead have their stroke brush data bound to the "color" property
    myDiagram.linkTemplate =
        { relinkableFrom: true, relinkableTo: true },  // allow the user to relink existing links
          { strokeWidth: 2 },
          new go.Binding("stroke", "color")),
          { toArrow: "Standard", stroke: null },
          new go.Binding("fill", "color"))

    // Define the appearance and behavior for Groups:

    // Groups consist of a title in the color given by the group node data
    // above a translucent gray rectangle surrounding the member parts
    myDiagram.groupTemplate =
      $(go.Group, "Vertical",
        new go.Binding("location", "", toLocation).makeTwoWay(fromLocation),
          selectionObjectName: "SHAPE",  // selection handle goes around shape, not label
          resizable: true, resizeObjectName: "SHAPE",
          ungroupable: true
        },  // enable Ctrl-Shift-G to ungroup a selected Group
            font: "bold 19px sans-serif",
            isMultiline: false,  // don't allow newlines in text
            editable: true  // allow in-place editing by user
          new go.Binding("text", "text").makeTwoWay(),
          new go.Binding("stroke", "color")),
        $(go.Shape, "Rectangle",  // the rectangular shape around the members
          { name: "SHAPE", fill: "rgba(128,128,128,0.2)", stroke: "gray", strokeWidth: 3 },
          new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify)),

    // Define the behavior for the Diagram background:

    // Create the Diagram's Model:
    var nodeDataArray = [
      { key: 1, text: "Alpha", color: "lightblue", loc: "0 0" },
      { key: 2, text: "Beta", color: "orange", loc: "100 0" },
      { key: 3, text: "Gamma", color: "lightgreen", group: 5, loc: "10 30" },
      { key: 4, text: "Delta", color: "pink", group: 5, loc: "100 100" },
      { key: 5, text: "Epsilon", color: "green", isGroup: true, loc: "50 100", size: "170 130" }
    var linkDataArray = [
      { from: 1, to: 2, color: "blue" },
      { from: 2, to: 2 },
      { from: 3, to: 4, color: "green" },
      { from: 3, to: 1, color: "purple" }
    myDiagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
<body onload="init()">
<div id="sample">
  <div id="myDiagramDiv" style="border: solid 1px black; width:400px; height:400px"></div>
  <pre id="savedModel"></pre>

Thanks, Please help me, I am in trouble last 1 week to fix this issue.