ReactOverview with ReactDiagram

What is the correct way to use the react overview with a react diagram?

The only example I could find seems to be referencing the diagram to observe from the state, which doesn’t seem correct (we have to put the entire diagram in the state?), and it also doesn’t seem to take a diagramRef from react (or a diagramref.current?.getDiagram())

It would be nice if we could pass a RefObject<ReactDiagram> to the observeDiagram property, unless I’m missing something?

A Diagram and its Nodes and Links are all part of the “view” of the “model” (i.e. of the props). So one would not want to put a Diagram or any Nodes or Links in the props.

What’s wrong with setting the property to a reference to a Diagram?

I’m not sure where to get that direct reference from a reactDiagram though. The init hasn’t been called when the startup code is running, and so the only reference I can get is the RefObject, which isn’t accepted. Even if I make my init something like

let diagramreference:go.Diagram;
initDiagram {
   diagramreference = go.Make(diagram);
   return diagramreference;
}

I can’t reference it in the ReactOverview because it’s not been initialized yet.

<ReactOverview
  initOverview={initOverview}
  divClassName="diagram-overview-div"
  observedDiagram={diagramReference}
/>

I’m not positive, but I think for the react overview to be usable with a react diagram it needs to be able to take a reference object. Do you guys have a sample or example somewhere using both a react diagram and a react overview I can look at? That would probably answer my question.

We’re looking into this.

1 Like

Here’s a CodeSandbox that demonstrates one of the ways you can set up a ReactOverview. It seems as though there’s currently an initialization issue causing the diagram to be positioned improperly. We’re investigating.

Hmm, I tried the diagramref.current approach and did not have success.

I’m not using a component, which I suspect may be the cause.

I stripped your example way down to recreate the issue ( I think this link should work ):

Sorry for the delay. Interesting, I’ll check it out.

I see. The problem is that you need to rerender after the ref has been initialized from the first render. In the class component, this is done in the componentDidMount function. In a functional component, you probably should use useState and a callback ref to trigger a rerender once ReactDiagram has rendered.

The reasoning is similar to if you wanted to measure a DOM node:

Demo:

1 Like

So this solution has fixed my problem, but it’s broken all of my functions that relied on the diagram reference. I assume there’s some way for me to get that diagram reference back.

E.g. how do I make the resetZoom function work?

The CommandHandler.resetZoom method can be called just like any other method. Something like: someDiagram.commandHandler.resetZoom().

Yeah the point is getting that diagram reference. Because with that fix, the render doesn’t actually create the diagram, and the reference is only ever defined in the callback. I need a way to get the “someDiagram” reference outside that, in order to trigger anything on it.

in my example, I can try calling diagram.zoomToFit(), but diagram is always null, because it’s never set there.

I’m not sure I understand. You should be able to use the “diagram” reference elsewhere, so long as it’s been initialized via the first render. Example, try zooming the diagram then hitting the Reset Zoom button:

I’m confused. The reset zoom button works, but if you use the doubleClick on the diagram, triggering the same function just via a gojs element, it doesn’t. How do you add a click handler to a node template (rather than a react element)?
image

$(go.Node, . . .,
  {
    click: function(e, node) { e.diagram.zoomToFit(); }
  },
  . . .
)

Although I would not recommend defining such a click event handler on any Node or Link, due to its causing an unusual effect.
https://gojs.net/latest/intro/events.html

The problem is actually that diagram has two different meanings during the initDiagram function. If you rename that diagram variable to myDiagram such that it doesn’t have a name collision with the diagram in state, it all works.

Maybe I’m misunderstanding what you mean, but I still see the issue even if I remove that diagram reference entirely, the only diagram reference is the one in state, and the double click still does not work:

Huh, it was working for me a minute ago, but isn’t now. Probably something related to CodeSandbox not reloading after I made experimental changes.

Anyway, there’s probably a better way of handling this. Really, the function being assigned to Diagram.doubleClick should not be the same as the one handling some HTML button click, as they are bound at different times.

If you define the Diagram.doubleClick like this, it should work as expected:

  doubleClick: (e: go.InputEvent) => {
    e.diagram.zoomToFit();
  },

Yeah I don’t use html buttons (almost) anywhere. I’m mostly just concerned about the diagram templates.

Should I be at all worried about the effects Walter mentioned?

Although I would not recommend defining such a click event handler on any Node or Link, due to its causing an unusual effect.

He mentioned that just because other things typically happen when clicking a node/link, like selection.

The only thing to think about is the ClickCreatingTool, which could also be activated by a double-click on the diagram background. If you’re not using that, or aren’t using double-click to activate it, you’ll be fine.

Ah okay, yeah I don’t do any creation, just selection changes on click. I changed most of my handlers over and it appears to be working. Thanks guys!