react-graph-vis icon indicating copy to clipboard operation
react-graph-vis copied to clipboard

Trying to show a context menu on right click event

Open MarcosFP97 opened this issue 6 years ago • 2 comments

Hi, I found myself in a hurry since I'm trying to implement an event that shows a context menu when a user right clicks in a node or in an edge of his or her graph. I've tried different approaches (using a ref to access api functions like getPositions or the function getNodeAt), but no one seemed to work. This is a simplification of the component I'm working with:

export class MainPage extends Component { constructor(props) { super(props)

this.state = {
    graph: {
        nodes: [
            {id: 1, label: "Twitter texts"},
            {id: 2, label: "Reddit comments"},
            {id: 3, label: "Reddit submissions"}
        ],
        edges: []
    },
    options: {
        layout: {
            hierarchical: {
                levelSeparation: 150,
                nodeSpacing: 150,
            }
        },
        edges: {
            color: "#000000"
        },
        height: '1000px',
        width: '1300px'
    },
    events: {
        oncontext: this.right_click,
    }
}

} right_click = (event) => { //show popup... } render() { return ( <div id={"mygraph"}> <Graph graph={this.state.graph} options={this.state.options} events={this.state.events} ref={ref => (this.g = ref)} />; ) } }

I'll appreciate any help. Thanks with your awesome work with vis. Regards, Marcos

MarcosFP97 avatar May 09 '19 21:05 MarcosFP97

Apologies for the necropost. This is for completion of the record, as this is a top Google result when I was searching for a solution to this issue.

From the example in README.md, it seems you can get access to the "network" object via the following property (https://github.com/crubier/react-graph-vis):

    <Graph
      graph={graph}
      options={options}
      events={events}
      getNetwork={network => {
        //  if you want access to vis.js network api you can set the state in a parent component using this property
      }}
    />

From there, the vis.js network module documentation states the following about the "oncontext" event (https://visjs.github.io/vis-network/docs/network/#event_oncontext):

oncontext | same as click. | Fired when the user click on the canvas with the right mouse button. The right mouse button does not select by default. You can use the method getNodeAt to select the node if you want.

The following additions to your code should point you in the right direction with one caveat. I'm having an issue lining up the event.pointer.DOM coordinate if the page has been scrolled or resized. As my use of this was on an internal utility page, this issue has not been pursued at this time.

export class MainPage extends Component {
  constructor(props) {
    super(props)

    this.state = {
        graph: {
            nodes: [
                {id: 1, label: "Twitter texts"},
                {id: 2, label: "Reddit comments"},
                {id: 3, label: "Reddit submissions"}
            ],
            edges: []
        },
        options: {
            layout: {
                hierarchical: {
                    levelSeparation: 150,
                    nodeSpacing: 150,
                }
            },
            edges: {
                color: "#000000"
            },
            height: '1000px',
            width: '1300px'
        },
        events: {
            oncontext: this.right_click,
        },
        network: null
    }
  }
  
  right_click = (event) => {
    if( this.state.network ) {
      let nodeid = this.state.network.getNodeAt( event.pointer.DOM );
      let edgeid = this.state.network.getEdgeAt( event.pointer.DOM );
      let edgenodes = this.state.network.getConnectedNodes( edgeid );
      //show popup...
    }
  }
  
  render() {
    return (
      <div id={"mygraph"}>
      <Graph
        graph={this.state.graph}
        options={this.state.options}
        events={this.state.events}
        ref={ref => (this.g = ref)}
        getNetwork={(network) => {this.setState({ network });}}
      />;
    )
  }
}

HappyFunTimes01 avatar Feb 16 '20 18:02 HappyFunTimes01

Maybe you can try using network.on("oncontext", function (params)

GustiDDI avatar Jan 26 '24 03:01 GustiDDI