<script src="https://gojs.net/latest/release/go.js"></script>
<div id="myDiagramDiv"></div>
#myDiagramDiv {
  height: 800px;
  width: 900px;
  border: 1px solid black;
}
var $ = go.GraphObject.make;  // for conciseness in defining templates
        myDiagram = $(go.Diagram, "myDiagramDiv", {
            "undoManager.isEnabled": true,
            allowDrop: true
        });

// Radio Button Node
        myDiagram.nodeTemplateMap.add("RadioButtonNode",
            $(go.Node, "Auto",
                { selectionAdorned: false, margin: 4, locationSpot: go.Spot.Center },
                $(go.Panel, "Horizontal",
                    $(go.TextBlock,
                        {
                            name: "LABEL_TEXT",
                            margin: 5,
                            text: "label",
                            editable: true,
                            isMultiline: false
                        },
                        new go.Binding("text", "labelText")
                    ),
                    $(go.Shape, "Circle",
                        {
                            strokeWidth: 1,
                            name: "SHAPE",
                            desiredSize: new go.Size(12, 12),
                            fill: "white",
                            click: function (e, shape) {
                                var diagram = e.diagram;
                                myDiagram.startTransaction("Change radio button");
                                if (shape.part.data.group) {
                                    var relatedRadios = diagram.findNodesByExample({ group: shape.part.data.group });
                                    relatedRadios.iterator.each(function (radio) {
                                        radio.findObject("SHAPE").fill = "white"
                                    });
                                }
                                shape.fill = "black";
                                myDiagram.commitTransaction("Change radio button");
                            }
                        })
                )));

myDiagram.nodeTemplate =
    $(go.Node, "Table",  
      { selectionAdorned: false },
      $(go.TextBlock,  
        { column: 0, margin: 3,
          textValidation: function(textblock, oldstr, newstr) {
            return !(isNaN(newstr));
          }
        },
        new go.Binding("text", "key", function(t) { return t + ": "; })
      ),
      $(go.Panel, "Auto",
        { column: 1, 
         stretch: go.GraphObject.Vertical 
        },
        $(go.Shape, { fill: "white" }),
        $(go.TextBlock, 
          {
            name: "CURRENT_SPINNER_VALUE", 
            editable: true,
            text: 10, width: 50
          },
          new go.Binding("text", "val").makeTwoWay()
        )
      ),
      $(go.Panel, "Vertical",
        { column: 2 },
        $("Button",
          $(go.Shape, "TriangleUp", { height: 5, width: 8 }),
          {
            click: function(e, obj) {
              var node = obj.part;
              e.diagram.startTransaction("Increment spinner");
              var spinnerVal = node.findObject("CURRENT_SPINNER_VALUE").text;
              node.findObject("CURRENT_SPINNER_VALUE").text = parseInt(spinnerVal) + 1;
              e.diagram.commitTransaction("Increment spinner");
            }
          }
        ),
        $("Button",
          $(go.Shape, "TriangleDown", { height: 5, width: 8 }),
          {
            click: function(e, obj) {
              var node = obj.part;
              e.diagram.startTransaction("Decrement spinner");
              var spinnerVal = node.findObject("CURRENT_SPINNER_VALUE").text;
              node.findObject("CURRENT_SPINNER_VALUE").text = parseInt(spinnerVal) - 1;
              e.diagram.commitTransaction("Decrement spinner");
            }
          }
        )
       )
    );

myDiagram.groupTemplate =  $(go.Group, "Horizontal",
      $(go.Panel, "Auto",
        $(go.Shape, "Rectangle", {fill: "white"}),  // surrounds the Placeholder
        $(go.Placeholder,    // represents the area of all member parts,
          { padding: 5})  // with some extra padding around them
      )
    );

myDiagram.model.nodeDataArray = [
  { key: "mainGroup", isGroup: true},
  { key: "group1", isGroup: true, group: "mainGroup"},
  { key: 1, category: "RadioButtonNode", group: "group1"},
  { key: 2, category: "RadioButtonNode", group: "group1"},
  { key: "Breadth", val: 20, group: "mainGroup" }
]
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.