Command Bar in GOJS

Hey, I want to integrate CommandBar in GOJS to create an onboarding journey. For this I would want command bar to detect the nodes created on the canvas. Is this possible? what would you suggest for giving a product tour of nodes created in GOJS?

Command Bar link

Just set Diagram.renderer to “svg”.
Look at the “data-…” attributes to get a clue for what’s what.

You can listen for changes to the node data array programmatically if you just need an event on each new node, using ModelChanged

        myDiagram = new go.Diagram(
          'myDiagramDiv', // create a Diagram for the HTML Div element
          {
            ModelChanged: (e) => {
              if (e.isTransactionFinished) {
                const tx = e.object;
                if (tx instanceof go.Transaction) {
                  console.log(tx.toString());
                  tx.changes.each((c) => {
                    // consider which ChangedEvents to inspect and do something with that information
                    if (c.model && c.propertyName === 'nodeDataArray') {
                      console.log('  ' + c.toString());
                      console.log(c);
                      // c.newValue would be the node data for the new node
                    }
                  });
                }
              }
            },
          }
        );

Hey Walter, after changing the renderer to svg, my iconPanel animations are behaving weird. Sharing the screen recording below. Not sure what is causing this issue.

GOJS Animation issue

code snippet of onMouseEnter

const animation = new go.Animation();
  animation.duration = 300;
  const iconPanel = node.findObject("NODEICON");
  const hoverPanel = node.findObject("HOVEROVERLAY");
  const mainPanel = node.findObject("SELECTIONADORNMENTGO");
  // debugger;
  hoverPanel.width = mainPanel.width;
  hoverPanel.height = mainPanel.height;
  // animation.add(hoverPanel, "width", 0, mainPanel.width);
  // animation.add(hoverPanel, "height", 0, mainPanel.height);
  animation.add(iconPanel, "scale", 1, 1.1);
  animation.start();

also i had to the change “fill” prop to “background” on my hoveroverlay panel for it to work properly after changing renderer to svg.

$(
      go.Panel,
      "Spot",      
      $(go.Shape, "RoundedRectangle", {
        width: 200,
        height: 150,
        fill: "white",
        stroke: "#E4E5E8",
        name: "SELECTIONADORNMENTGO",
        shadowVisible: true,
        parameter1: 12,
      }),
      $(
        go.Panel,
        "Spot",
        { isClipping: true },
        $(go.Shape, "RoundedRectangle", {
          width: 200,
          height: 150,
          fill: "transparent",
          stroke: "transparent",
          parameter1: 12,
        }),
        $(
          go.Picture,
          { width: 200, height: 150, name: "NODEICON" },
          new go.Binding("source", "_src")
        )
      ),      
      $(
        go.Panel,
        "Spot",
        { isClipping: true },
        $(go.Shape, "RoundedRectangle", {
          width: 0,
          height: 0,
          // fill: "#263238",
          background: "#263238",
          opacity: 0.2,
          name: "HOVEROVERLAY",
          stroke: "transparent",
          parameter1: 12,
        })
      )
    )

This is most likely a bug with the SVG renderer.

Could you give me the whole Node template?

$(
  go.Node,
  $(
    go.Panel,
    "Spot",
    $(
      go.Panel,
      "Spot",
      {
        mouseEnter: (e, node) => {
          enterAnimation(node);
        },
        mouseLeave: (e, node, nextObj) => {
          exitAnimation(node);
        },
      },
      $(go.Shape, "RoundedRectangle", {
        width: 200,
        height: 150,
        fill: "white",
        stroke: "#E4E5E8",
        name: "SELECTIONADORNMENTGO",
        shadowVisible: true,
        parameter1: 12,
      }),
      $(
        go.Panel,
        "Spot",
        { isClipping: true },
        $(go.Shape, "RoundedRectangle", {
          width: 200,
          height: 150,
          fill: "transparent",
          stroke: "transparent",
          parameter1: 12,
        }),
        $(
          go.Picture,
          { width: 145, height: 145, name: "NODEICON" },
          new go.Binding("source", "_src")
        )
      ),
      $(go.Shape, "Circle", {
        cursor: "pointer",
        fill: "transparent",
        stroke: "transparent",
        width: 1,
        height: 1,
        portId: TO_PORT,
        alignment: go.Spot.Left,
        toSpot: go.Spot.Left,
        toLinkable: true,
      }),
      $(go.Shape, "Circle", {
        fill: "transparent",
        stroke: "transparent",
        width: 1,
        height: 1,
        portId: FROM_PORT,
        alignment: go.Spot.Right,
        fromSpot: go.Spot.Right,
        fromLinkable: true,
        name: "FROMPORTGO",
      }),
      $(go.Shape, "RoundedRectangle", {
        width: 0,
        height: 0,
        background: "#263238",
        opacity: 0.2,
        name: "HOVEROVERLAY",
        stroke: "transparent",
        parameter1: 12,
      })
    ),
  ),
  new go.Binding("location", "location", go.Point.parse).makeTwoWay(
    go.Point.stringify
  )
);

Enter Animation

(node) => {
  const animation = new go.Animation();
  animation.duration = 300;
  const iconPanel = node.findObject("NODEICON");
  const hoverPanel = node.findObject("HOVEROVERLAY");
  const mainPanel = node.findObject("SELECTIONADORNMENTGO");
  hoverPanel.width = mainPanel.width;
  hoverPanel.height = mainPanel.height;
  // animation.add(hoverPanel, "width", 0, mainPanel.width);
  // animation.add(hoverPanel, "height", 0, mainPanel.height);
  animation.add(iconPanel, "scale", 1, 1.1);
  animation.start();
};

Exit Animation

(node) => {
  const animation = new go.Animation();
  animation.duration = 300;
  const iconPanel = node.findObject("NODEICON");
  const hoverPanel = node.findObject("HOVEROVERLAY");
  // const mainPanel = node.findObject("SELECTIONADORNMENTGO");
  hoverPanel.width = 0;
  hoverPanel.height = 0;
  // animation.add(hoverPanel, "width", mainPanel.width, 0);
  // animation.add(hoverPanel, "height", mainPanel.height, 0);
  animation.add(iconPanel, "scale", 1.1, 1);
  animation.start();
};

Thanks, I see the issue. We’ll investigate a fix.

Just to add to the above, even the canvas scaling doesn’t work correctly when the renderer is svg. The scale changes can be seen in the overview but not on the canvas

Thanks, I see the issue. We’ll investigate a fix.

Hey Simon, is this fixed?

Hey walter, I still need help on this. I want to create a nudge to the user, whenever a node is created or added to the canvas, using commandbar. Since commandbar works on css or xpath and my nodes are created dynamically with node key equal to the timestamp, not quite sure how to get this done. Any help is appreciated.

I believe this has been fixed – update to latest.

Hey Walter, the fix only solves the weird display bug when using svg renderer.

I want to know if CommandBar is compatible with GOJS.

For example, whenever the diagram adds a node (whose key is a timestamp) to the canvas, can commandbar detect that and trigger a nudge to the user to double click the newly add node, by showing a commandbar popup next to the node like “eg. double click this node to configure it”.

We are completely unfamiliar with Command Bar. If it can traverse the DOM it should be able to examine all of the Nodes and Links in the Diagram. Maybe you need to give it clues for what to look for?

Or maybe you need to translate the graph into something it can parse?