How to give size to adornment and can give custom shape to it

Just set or bind https://gojs.net/latest/api/symbols/Shape.html#geometryString.

$(go.Shape,
  {
    geometryString: "...path...",
    . . .
  })

or

$(go.Shape,
  new go.Binding("geometryString", "geo"),
  { . . . })

where your data has:

  { geo: "...path...", . . . }

But i am registering that shape also so that i can use it in Palette and diagram

this.diagram.nodeTemplateMap.add("xor", xorTemplate);
this.diagram.nodeTemplateMap.add("custom", customTemplate);
this.palette = new go.Palette();
this.palette.nodeTemplateMap = this.diagram.nodeTemplateMap;
this.palette.model.nodeDataArray =
  [
    { text: "Alpha", color: "lightblue" },
    { text: "Beta", color: "orange" },
    { text: "Gamma", color: "lightgreen" },
    { text: "Delta", color: "pink" },
    { text: "Epsilon", color: "yellow" },
    {category: "xor"},
    {category: "custom"}
  ];

Also can we switch the Adornment off if we are selecting it in palette. Right now it is getting triggered in palette too.

Using a template in multiple situations, such as for different diagrams, is completely independent of using named Shape figures. That is because defining templates is completely independent of defining named figure generators.

For your second question, if you have defined a node template that includes a setting of Part.selectionAdornmentTemplate, then wherever you use that template you will get all of its settings, including selectionAdornmentTemplate. But you could make a copy of the template and modify it, either by setting selectionAdornmentTemplate to null or by setting Part.selectionAdorned to false. BUT, you cannot simply copy a template. Instead, generate the template, modifying it to suit your needs.


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

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
          {
            layout: $(go.TreeLayout)
        });

    // Copying templates does not work -- bindings are lost.
    // Instead make templates programmatically and change their structure and/or properties.

    function makeTemplate(cmElement) {
      var template = $(go.Node, "Auto",
        new go.Binding("location", "loc").makeTwoWay(),
        $(go.Shape,
          { fill: "white" },
          new go.Binding("fill", "color")),
        $(go.TextBlock,
          { margin: 8 },
          new go.Binding("text"))
      );
      if (cmElement) {
        var elt = document.getElementById(cmElement);
        if (elt) {
          elt.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; }, false);
          template.contextMenu =
            $(go.HTMLInfo,
              {
                show: function(obj, diag, tool) {
                  elt.style.display = "block";
                  var mousePt = diag.lastInput.viewPoint;
                  elt.style.left = mousePt.x + "px";
                  elt.style.top = mousePt.y + "px";
                  elt.innerHTML = "<button>some command for " + obj.part.data.text + " </button>";
                },
                mainElement: elt
              });
        }
      }
      return template;
    }

    myDiagram.nodeTemplate = makeTemplate();;
    myDiagram.nodeTemplateMap.add("Two", makeTemplate("myCM"));

    myDiagram.model = new go.GraphLinksModel(
    [
      { key: 1, text: "Alpha", color: "lightblue" },
      { key: 2, text: "Beta", color: "orange", category: "Two" },
      { key: 3, text: "Gamma", color: "lightgreen", category: "Two" },
      { key: 4, text: "Delta", color: "pink" }
    ],
    [
      { from: 1, to: 2 },
      { from: 1, to: 3 },
      { from: 3, to: 4 }
    ]);
  }

I am not able to resize that Figure i generated using FigureGenerator, that may be because i am not using that shape, height and width parameters. How can i utilize that if i am using Geo strings for creating the image.
I want resizing capabilities for shapes that i register using SVG path as geo in figure generator.

Hi @walter can we alter the properties of the adornment if it hits or enters another object defined in our diagram and for that exposed area only something like in below image


Setting Stroke dash array for the area that is going out of a Rectangle figure.

Shape.stroke… properties apply to the whole shape, so that will not work to affect only a piece of the shape.

I would draw horizontal white (background color) bars where those special objects are. If there is only one such object, you could add a “Grid” Panel to your Adornment that is in front of the shape. https://gojs.net/latest/intro/grids.html

You would need to control the size and position of that panel in the adornment’s local coordinates to match the actual document coordinates of that special object, which I hope is rectangular.

@walter And what about figure generator which is using SVG path as Geo string how to resize such shapes.

As I keep saying, you do not want to define a figure generator for the usage that you describe.

How can i achieve the following functionality with go.Shape

  1. It should be available in palette.
  2. It should be drag-able to diagram window.
  3. 2 way binding should be done so that can be saved and loaded to and from model.
  4. Should be re-sizable to a given dimension.
  5. Selection Adornment
    All of this using SVG path as Geometry.
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
  <script src="go.js"></script>

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

      // initialize main Diagram
      myDiagram =
        $(go.Diagram, "myDiagramDiv",
          {
            "undoManager.isEnabled": true
          });

      myDiagram.nodeTemplate =
        $(go.Node, "Vertical",
          { resizable: true, resizeObjectName: "SHAPE", selectionObjectName: "SHAPE" },
          new go.Binding("location", "location", go.Point.parse).makeTwoWay(go.Point.stringify),
          $(go.Shape,
            {
              name: "SHAPE",
              geometryString: "M20 18c3.308 0 6.308 1.346 8.481 3.519l-2.827 2.827c-1.449-1.449-3.449-2.346-5.654-2.346s-4.206 0.897-5.654 2.346l-2.827-2.827c2.173-2.173 5.173-3.519 8.481-3.519zM5.858 15.858c3.777-3.777 8.8-5.858 14.142-5.858s10.365 2.080 14.142 5.858l-2.828 2.828c-3.022-3.022-7.040-4.686-11.314-4.686s-8.292 1.664-11.314 4.686l-2.828-2.828zM30.899 4.201c3.334 1.41 6.329 3.429 8.899 6v0l-2.828 2.828c-4.533-4.533-10.56-7.029-16.971-7.029s-12.438 2.496-16.971 7.029l-2.828-2.828c2.571-2.571 5.565-4.589 8.899-6 3.453-1.461 7.12-2.201 10.899-2.201s7.446 0.741 10.899 2.201zM18 28c0-1.105 0.895-2 2-2s2 0.895 2 2c0 1.105-0.895 2-2 2s-2-0.895-2-2z",
              fill: "white", stroke: "pink"
            },
            new go.Binding("stroke", "color"),
            new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify)),
          $(go.TextBlock,
            { font: "12pt sans-serif", editable: true },
            new go.Binding("text").makeTwoWay())
        );

      // initialize Palette
      myPalette =
        $(go.Palette, "myPaletteDiv",
          {
            nodeTemplateMap: myDiagram.nodeTemplateMap
          });

      // now add the initial contents of the Palette
      myPalette.model.nodeDataArray = [
        { text: "blue node", color: "blue" },
        { text: "orange node", color: "orange" }
      ];

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

      load();
    }

    // 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() {
      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: whitesmoke; border: solid 1px black"></div>
      <div id="myOverviewDiv" style="margin: 2px 0 0 0; width: 100px; height: 100px; background-color: lightgray; 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": "go.GraphLinksModel",
  "nodeDataArray": [
{"key":1, "text":"hello", "color":"green", "location":"0 0"},
{"key":2, "text":"world", "color":"red", "location":"70 0"}
  ],
  "linkDataArray": [
{"from":1, "to":2}
  ]}
  </textarea>
</body>
</html>

Tried Go.Shape but resizing is not working

var customTemplate=
    $(go.Node, 
      "Spot", nodeStyle(),  
      {
        selectionAdornmentTemplate:  // custom selection adornment
        $(go.Adornment, "Spot",
        $(go.Placeholder),
        $(go.Shape,
          {
            geometryString: CustomFigures.ADNx,
            alignment: go.Spot.Center,
            alignmentFocus: go.Spot.Left,
            stroke: "pink"
          })
        )
      },
      $(go.Shape, 
        {
          name: "NX", 
          geometryString: CustomFigures.Nx, 
          width: 90, 
          height:30,
          stroke: "red",  
          fill: "lightgray"      
        },
      new go.Binding("figure", "key")),
      { rotatable: true, rotateObjectName: "customFigure" },
      { resizable: true, resizeObjectName: "customFigure" }
    );
    this.diagram.nodeTemplateMap.add("custom", customTemplate);

Oh sorry, just figured object name is incorrect. working fine now able to resize it.
Thanks @walter

Hi @walter when i was using figure generator i was able to bind angle in the model but now it’s not working. i am not getting angle in the model. I am binding the angle. Also adornment is not moving with angle after using Shape instead of figure generator.

I have to do something like this to achieve that. Why the name property is not working for it?
And this Custom is FigureGenrated Figure

$(go.Shape, "Custom",
        {
          name: "NX", 
          geometryString: CustomFigures.Nx, 
          width: 90, 
          height:30,
          stroke: "red",  
          fill: "lightgray",
          geometryStretch: go.GraphObject.Uniform,   
        },
   new go.Binding("figure", "key")),
  { rotatable: true, rotateObjectName: "Custom" },
  { resizable: true, resizeObjectName: "NX" },      
  new go.Binding("angle").makeTwoWay(),

Hi @walter don’t know why but the adornment is getting hidden for some angles at a particular location.
Seems to be happening only for the left side of the diagram when there is not enough space on the diagram window and if scroll up works fine



Without Scroll

image

Scroll Up:

image

You could try increasing Diagram.padding to a value large enough to include your adornment.

And what about the rotation Issue with figure.

Does your Adornment also have a Binding on angle? Note that all bindings in the Adornment can be OneWay.

Not Adornment but the main entity for which we used Shape and Geometry string. i am not able to get its angle in Model even after binding the angle two way. but it works fine if i give cutsomFigureGenrated figure name with the shape like in this code.

In Code it is not Adornment but the main template of the custom shape.