Showing "preview" of new links on dragEnter of node

Referring to the solution for this post: https://forum.nwoods.com/t/inserting-a-node-on-an-existing-link-automatically/8402.

My modified solution to achieve the “insert node on existing link” functionality is as follows:

function dropTaskOnTransition(e, oldlink) {
  const { diagram } = e;
  const { type, state } = oldlink.data;
  const newTask = diagram.selection.first();
  if (newTask.linksConnected.count > 0) return;
  const toTask = oldlink.toNode;
  // Reconnect the existing link to the new node
  oldlink.toNode = newTask;
  // Then add links from the new node to the old node
  diagram.model.addLinkData({
    type,
    state: state === 'loop' ? 'success' : state,
    from: newTask.key,
    to: toTask.key,
  });
}

...

mouseDragEnter: (e, link) => {
        link.opacity = 0.3;
        link.isShadowed = true;
      },
mouseDragLeave: (e, link) => {
        link.opacity = 1;
        link.isShadowed = false;
      },
mouseDrop: dropTaskOnTransition

At the moment, the dragEnter/hover interaction is reducing the opacity. How would I go about implementing a preview of what the new links would look like onDragEnter and only adding to the model data on drop, like currently implemented?

Thanks in advance for any information you can provide!

Create an unmodeled Node and two unmodeled Links that are just like what you expect will exist if the drop happens. Put the temporary Node and Links in the “Tool” Layer so that they are in front of everything and so that those changes aren’t recorded in the UndoManager.

Unrelated example of adding unmodeled Nodes and Links to a Diagram: Unbound Parts

Unrelated example of adding unmodeled Links to a Diagram: A Tree with Sequencing Links between Sibling Nodes

Unrelated example of adding unmodeled Parts to a Diagram: Benchmark

@walter Thanks for these examples! These got me close to my end goal. Calling the following function on mouseDragEnter of the current link successfully adds the unmodeled links to the diagram but when it reaches the attempt to add the unmodeled node, the app crashes with the error below.

function createPreviewTransition(diagram, task1, task2, task3, link) {
  const { type, state } = link.data;
  // add an unmodeled Link to the Diagram -- Link.data will be null
  const tempLink1 = tempLinkTemplate(type, state);
  const tempLink2 = tempLinkTemplate(type, state, true);

  tempLink1.fromNode = task1;
  tempLink1.toNode = task2;
  tempLink2.fromNode = task2;
  tempLink2.toNode = task3;
  tempLink1.layerName = 'Tool';
  tempLink2.layerName = 'Tool';
  tempLink1.part.name = 'tempLink';
  tempLink2.part.name = 'tempLink';

  diagram.add(tempLink1);
  diagram.add(tempLink2);
  diagram.add(
    GraphObject.make(
      Node,
      'Auto',
      GraphObject.make(Shape, 'RoundedRectangle', { fill: 'lightblue' }),
      GraphObject.make(TextBlock, 'Hello!', { margin: 5 }),
    ),
  );
}

Any suggestions as what may be causing this issue and any potential solutions? I believe I am adding the unmodeled node the same as the examples.

I don’t understand the error message – what was it that isn’t a constructor?

I assume you have imported all of the GoJS class names, so that you don’t need to use “go.” as a package prefix.

So it looks like it was complaining about Node being the constructor. I switched it to Part and it doesn’t crash anymore.

So now it works as expected except the newly added nodes don’t display on the diagram until the mouseDrop event, even though they are added during the mouseDragEnter. Say I mouseDragEnter the link 12 times, then once I drop, 12 nodes then appear instead of appearing on mouseDragEnter.

Check that you have correctly imported the Node identifier from the GoJS package. Maybe it’s thinking it’s an HTML DOM Node.

Do those newly added parts have real Node.locations? If there’s no real location for a Part GoJS won’t know where to draw it.

The Node identifier is correctly imported and it is used in other parts of the app as well, not sure what’s going on.

Regardless, adding the location property fixed the delayed rendering of the node, I think I am able to move forward at the moment, thanks for taking time to help with these blockers!