通过单击 GOJS 中的形状在形状上制作斑点

Make spots on shapes by clicking on the shape in GOJS

我正在使用 GOJS,每当我点击形状时我都想做一个点。这个点应该正好出现在我点击 shape.Can 的位置上,我这样做了吗? 这是我的代码,我添加了硬编码的点或端口

function makePort(name, spot, output, input) {
      return GO(go.Shape, "Circle",
               {
                  fill: "grey",  
                  stroke: null,
                  desiredSize: new go.Size(10, 10),
                  alignment: spot, 
                  alignmentFocus: spot,  
                  portId: name, 
                  fromSpot: spot, toSpot: spot,  
                  fromLinkable: output, toLinkable: input,  
                  cursor: "pointer"  
               });
    }
 myDiagram.nodeTemplate =
     GO(go.Node, "Spot",
     {

       selectionAdorned: false,  // don't show the standard selection handle
       resizable: true, resizeObjectName: "SHAPE",  // user can resize the Shape
        rotatable: true, rotateObjectName: "SHAPE",  // user can rotate the Shape
                                                     // without rotating the label
        layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutNodeSized
      },
      new go.Binding("location", "loc").makeTwoWay(),  // TwoWay Binding // Binds diagram and model location with eachother 
      a = GO(go.Shape,
        {
          click:click1,
          name: "SHAPE",
          width: 70, height: 70,
          stroke: "#000000",
          fill: "transparent",
          //angle: 45,
          strokeWidth: 1
        },
        new go.Binding("figure","fig"),
        new go.Binding("name_shape", "key"),
       new go.Binding("angle", "ang").makeTwoWay(),  // Binds diagram and model angle with eachother 
        // new go.Binding("desiredSize", "size").makeTwoWay(), // Binds diagram and model size with eachother 
        new go.Binding("geometryString", "geometry").makeTwoWay()),// Binds diagram and model geometry string with eachother 
      // GO(go.Shape,"Circle",  // the "A" port
      //       { width: 20, height: 20, portId: "A",stroke:null,toSpot: go.Spot.Left}),
      /*GO(go.Panel, "Vertical",
        GO(go.TextBlock,
          new go.Binding("text", "fig")),
        GO(go.TextBlock, { stroke: "blue" },
          new go.Binding("text", "parameter1", function(p1) { return p1; }).ofObject("SHAPE"))
      )*/
       // GO(go.Shape,  // the "A" port
       //      { width: 6, height: 6, portId: "A" }),

      // four small named ports, one on each side:
        makePort("T", go.Spot.Top, false, true),
        makePort("L", go.Spot.Left, true, true),
        makePort("TL", go.Spot.TopLeft, true, true),
        makePort("BL", go.Spot.BottomLeft, true, true),
        makePort("R", go.Spot.Right, true, true),
        makePort("TR", go.Spot.TopRight, true, true),
        makePort("BR", go.Spot.BottomRight, true, true),
        makePort("B", go.Spot.Bottom, true, true),
        makePort("C",go.Spot.Center,true,true),

        { // handle mouse enter/leave events to show/hide the ports
          mouseEnter: function(e, node) { showSmallPorts(node, true); },
          mouseLeave: function(e, node) { showSmallPorts(node, false); }
        }
    );

     function showSmallPorts(node, show) {
      node.ports.each(function(port) {
        if (port.portId !== "") {  // don't change the default port, which is the big shape
          port.fill = show ? "rgba(0,0,0,.3)" : null;
        }
      });

我认为这应该符合您的要求:

  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
        { initialContentAlignment: go.Spot.Center, "undoManager.isEnabled": true });

    myDiagram.nodeTemplate =
      $(go.Node, "Spot",
        { selectionObjectName: "BODY" },
        new go.Binding("itemArray", "spots"),
        { // each spot is represented by a Panel holding a circular Shape
          // at a particular alignment relative to the "BODY"
          itemTemplate:
            $(go.Panel,
              $(go.Shape, "Circle",
                {
                  fill: $(go.Brush, go.Brush.Radial, { 0.0: "gray", 1.0: "transparent" }),
                  strokeWidth: 0, width: 16, height: 16
                }),
              new go.Binding("alignment", "spot", go.Spot.parse).makeTwoWay(go.Spot.stringify)
            ),
          // when the user clicks on the node, add a "spot"
          click: function(e, obj) {
            e.diagram.startTransaction();
            // convert click point into Spot in node's bounds
            var pt = e.documentPoint;  // in document coordinates
            var node = obj.part;
            var b = node.actualBounds;  // will be in document coordinates
            var spot = new go.Spot(Math.max(0, Math.min((pt.x - b.x) / b.width, 1)),
                                   Math.max(0, Math.min((pt.y - b.y) / b.height, 1)));
            // add an Object describing the spot's location (as a Spot value)
            var spotsArray = node.data.spots;
            if (!Array.isArray(spotsArray)) spotsArray = node.data.spots = [];
            e.diagram.model.addArrayItem(spotsArray, { spot: go.Spot.stringify(spot) });
            e.diagram.commitTransaction("added spot");
          }
        },
        $(go.Panel, "Auto",
          { name: "BODY", width: 100, height: 100 },
          $(go.Shape, { fill: "whitesmoke" }),
          $(go.TextBlock, { editable: true },
            new go.Binding("text").makeTwoWay())
        )
      );

    myDiagram.model = $(go.GraphLinksModel,
      {
        copiesArrays: true,  // make sure the data.spots Array is copied
        copiesArrayObjects: true,  // make sure the Objects in those Arrays are also copied
        nodeDataArray: [
          { key: 1, text: "Alpha", spots: [] },
          { key: 2, text: "Beta", spots: [{ spot: "0.3, 0.2" }] }
        ],
        linkDataArray: [
          { from: 1, to: 2 }
        ]
      });
  }

执行此操作并单击几个位置的节点会导致:

请注意,"Beta" 节点以一个点开始,如模型数据中所定义。

顺便说一下,我不清楚用户想要添加的 "spots" 真的必须是 "ports"。您可以通过给每个 "spot" 一个 "port" 一个唯一的 GraphObject.portId.

您可能想阅读 GoJS 简介的所有页面,位于 http://gojs.net/latest/intro