<button onclick="showGroup(null)">Joint View</button>
  <button onclick="showGroup('g1')">Diagram 1</button>
  <button onclick="showGroup('g2')">Diagram 2</button>
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
  <textarea id="mySavedModel" style="width:100%;height:250px"></textarea>
/*.gsfBackground {
  border-color: #99aaa6;
  font-size: 11;
  margin-bottom: 8;
  }  */

.gsfBackground {
    border-color: #9b7fb8;
    font-size: 13;
    margin-bottom: 13;
  }
  function init() {
    var $ = go.GraphObject.make;
    var GroupMargin = new go.Margin(3);
    myDiagram =
      $(go.Diagram, "myDiagramDiv",
        {
          layout: $(go.TreeLayout, { isRealtime: true }),
            "resizingTool.computeMinSize": function() {
            var group = this.adornedObject.part;
            var membnds = group.diagram.computePartsBounds(group.memberParts);
            membnds.addMargin(GroupMargin);
            membnds.unionPoint(group.location);
            return membnds.size;
          },
      
          "undoManager.isEnabled": true,
          "ModelChanged": function(e) {     // just for demonstration purposes,
            if (e.isTransactionFinished) {  // show the model data in the page's TextArea
              document.getElementById("mySavedModel").textContent = e.model.toJson();
            }
          }
        });

    // have each group (i.e. diagram) be shown in a different layer
    myDiagram.addLayerBefore($(go.Layer, { name: "g1" }), myDiagram.findLayer(""));
    myDiagram.addLayerBefore($(go.Layer, { name: "g2" }), myDiagram.findLayer(""));

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        { // make sure each node that belongs to a group is in the same layer
            dragComputation: stayInGroup /*,  --- 
            containingGroupChanged: function(node, oldgrp, newgrp) {
            node.layerName = newgrp ? newgrp.key : "";
          }*/  // Removing this comment works as expected ...
        },
        //new go.Binding("layerName", "group"),  // This line was not there ...       
        new go.Binding("location").makeTwoWay(),
        { locationSpot: go.Spot.Center },
        $(go.Panel, "Spot",
          $(go.Panel, "Auto",
            $(go.Shape,
              { fill: "white", figure:"circle" },
              new go.Binding("fill", "color")),
            $(go.TextBlock,
              { margin: 1, editable: true },
              new go.Binding("text").makeTwoWay())
          )
        )
      );

    myDiagram.groupTemplate =
      $(go.Group, "Vertical", {  
          resizable: true,
          layout:  $(go.CircularLayout, { isRealtime: true }),
          layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutNodeSized,
          resizeObjectName: "SHAPE",
          selectionObjectName: "SHAPE" },
        new go.Binding("layerName", "key"),
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        $(go.Shape, { name: "SHAPE", figure:"circle", fill: "whitesmoke" },
          new go.Binding("desiredSize").makeTwoWay()),
        $(go.TextBlock,
          { font: "bold 13pt sans-serif", margin:15  },
          new go.Binding("text"))        
      );

    myDiagram.linkTemplate =
      $(go.Link,
        {
          fromPortId: "out", toPortId: "in",
          relinkableFrom: true, relinkableTo: true,
          containingGroupChanged: function(link, oldgrp, newgrp) {
            link.path.strokeWidth = newgrp ? 1 : 2;  // thicker if between groups
            link.layerName = newgrp ? newgrp.key : "";  // make sure link belongs to correct layer
          }
        },
        $(go.Shape, { strokeWidth: 2 }),
        $(go.Shape, { toArrow: "OpenTriangle" })
      );

    myDiagram.model =
      $(go.GraphLinksModel,
        {
          nodeDataArray:
            [
              { key: "g1", text: "Model 1", isGroup: true },
              { key: 1, text: "1", color: "lightblue", model: "1", group: "g1" },
              { key: 2, text: "2", color: "orange", group: "g1" },
              { key: 5, text: "3", color: "lightblue", model: "1", group: "g1"},
              { key: 6, text: "4", color: "orange", group: "g1"},
              { key: 7, text: "5", color: "lightblue", model: "1", group: "g1"},
              { key: 8, text: "6", color: "orange", group: "g1" },              
              { key: "g2", text: "Model 2", isGroup: true },
              { key: 3, text: "7", color: "lightgreen", group: "g2" },
              { key: 4, text: "8", color: "pink", group: "g2" },
              { key: 9, text: "9", color: "lightgreen", group: "g2" },
              { key: 10, text: "A", color: "pink", group: "g2" },
              { key: 11, text: "B", color: "lightgreen", group: "g2" },
              { key: 12, text: "C", color: "pink", group: "g2" },
              
            ],
          linkDataArray:
            [
            ]
        });
  

    // 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
      var grp = part.containingGroup;
      if (grp === null) return pt;
      // try to stay within the background Shape of the Group
      var 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;
      var p1 = back.getDocumentPoint(go.Spot.TopLeft);
      var p2 = back.getDocumentPoint(go.Spot.BottomRight);
      var b = part.actualBounds;
      var loc = part.location;
      // no placeholder -- just assume some Margin
      var m = new go.Margin(5);
      // now limit the location appropriately
      var x = Math.max(p1.x + m.left, Math.min(pt.x, p2.x - m.right - b.width - 1)) + (loc.x - b.x);
      var y = Math.max(p1.y + m.top, Math.min(pt.y, p2.y - m.bottom - b.height - 1)) + (loc.y - b.y);
      return new go.Point(x, y);
    }
  }

  function showGroup(key) {
    myDiagram.commit(function(diag) {
      diag.layers.each(function(layer) {
        //layer.visible = (!key || layer.name === key);
        layer.visible = layer.isTemporary || !key || (layer.name === key); // As per walter
      })
    }, null);  // don't record these changes in the UndoManager
  }

$(document).ready(init); //comment1
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
  2. https://gc-test.splitvision.nl/UI/scripts/go/go.js