Unique names on drag/drop

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <!-- Copyright 1998-2020 by Northwoods Software Corporation. -->
  <script src="https://unpkg.com/gojs"></script>
  <script>
    function init() {
      var $ = go.GraphObject.make;

      myDiagram =
        $(go.Diagram, "myDiagramDiv",
          {
            "undoManager.isEnabled": true,
            // don't start updating componentName counters until after the model has been loaded
            "InitialLayoutCompleted": function(e) { e.diagram.addModelChangedListener(onNodeDataAdded); }
          });

      myDiagram.nodeTemplate =
        $(go.Node, "Auto",
          new go.Binding("location", "location", go.Point.parse).makeTwoWay(go.Point.stringify),
          $(go.Shape,
            {
              fill: "white", stroke: "gray", strokeWidth: 4,
              portId: "", cursor: "pointer",
              fromLinkable: true, toLinkable: true,
              fromLinkableDuplicates: true, toLinkableDuplicates: true,
              fromLinkableSelfNode: true, toLinkableSelfNode: true
            },
            // assume componentName is also a color, so no converter needed
            new go.Binding("stroke", "componentName")),
          $(go.TextBlock,
            {
              margin: new go.Margin(5, 5, 3, 5), font: "10pt sans-serif",
              minSize: new go.Size(16, 16), maxSize: new go.Size(120, NaN)
            },
            new go.Binding("text"))
        );

      myPalette =
        $(go.Palette, "myPaletteDiv",
          {
            nodeTemplateMap: myDiagram.nodeTemplateMap,
            model: new go.GraphLinksModel([
              { text: "red node", componentName: "red" },
              { text: "green node", componentName: "green" },
              { text: "blue node", componentName: "blue" },
              { text: "orange node", componentName: "orange" }
            ])
          });

      myOverview =
        $(go.Overview, "myOverviewDiv",
          {
            observed: myDiagram,
            contentAlignment: go.Spot.Center
          });

      load();
    }

    // This is called on each Model Changed event after the model has been loaded.
    // Whenever a node data object has been added, increment the counter corresponding
    // to "componentName" and set the node data's "text" property to the desired string.
    // The counters are held in the shared Model.modelData object, which will remember
    // the componentName counts even if there are no nodes.
    // Changes to the counters are recorded in the UndoManager, so an undo will revert
    // the counts along with removing added nodes.
    function onNodeDataAdded(e) {
      if (e.change === go.ChangedEvent.Insert && e.propertyName === "nodeDataArray" &&
          !e.model.skipsUndoManager) {  // skip any temporary additions, such as during drag-and-drop
        var data = e.newValue;
        var cname = data.componentName;
        if (!cname) cname = "none";
        var counters = e.model.modelData;
        var count = counters[cname] || 0;
        count++;
        e.model.set(counters, cname, count);
        e.model.set(data, "text", cname + " " + count);
      }
    }

    // save a model to and load a model from Json text, displayed below the Diagram
    function save() {
      var str = myDiagram.model.toJson();
      document.getElementById("mySavedModel").value = str;
    }
    function load() {
      // disable onNodeDataAdded while the model is being loaded
      myDiagram.removeModelChangedListener(onNodeDataAdded);
      var str = document.getElementById("mySavedModel").value;
      myDiagram.model = go.Model.fromJson(str);
    }
  </script>
</head>
<body onload="init()">
  <div style="width: 100%; display: flex; justify-content: space-between">
    <div style="display: flex; flex-direction: column; margin: 0 2px 0 0">
      <div id="myPaletteDiv" style="flex-grow: 1; width: 100px; background-color: floralwhite; border: solid 1px black"></div>
      <div id="myOverviewDiv" style="margin: 2px 0 0 0; width: 100px; height: 100px; background-color: whitesmoke; border: solid 1px black"></div>
    </div>
    <div id="myDiagramDiv" style="flex-grow: 1; height: 400px; border: solid 1px black"></div>
  </div>
  <div id="buttons">
    <button id="loadModel" onclick="load()">Load</button>
    <button id="saveModel" onclick="save()">Save</button>
  </div>
  <textarea id="mySavedModel" style="width:100%;height:200px">
  { "class": "GraphLinksModel",
    "modelData": {"red":1, "green":1, "blue":0, "orange":0, "none":0},
    "nodeDataArray": [ 
  {"key":1, "text":"green 1", "componentName":"green", "location":"0 0"},
  {"key":2, "text":"red 1", "componentName":"red", "location":"90 0"}
   ],
    "linkDataArray": [ {"from":1, "to":2} ]}
  </textarea>
</body>
</html>