2

Iam trying to implement: original node should stay in its position and doing drag and drop on it, has to create a new node at drop location. Original should stay at initial position.

dragging duplicate node should just change its position.

import React, { Component, MouseEvent } from 'react'
import ReactFlow from 'react-flow-renderer'

export default class Platform extends Component {

    constructor(props) {
        super(props)
        
    
        this.state = {
             duplicates : [],
             original: [{id: "original", data: {label: 'original', duplicate: false }, position: {x:100, y:100}, style: this.style}]
        }
    }

    lastId = 0
    style = { background: '#ccc', width: 50, height: 50, borderRadius: 50}


    onNodeDragStart = (evt: MouseEvent, node: Node) => {
    }


    onNodeDragStop = (evt: MouseEvent, node: Node) => {
        if(!node.data.duplicate){
            node.id = (this.lastId++).toString(10)
            node.data.duplicate = true
            node.data.label = "duplicate"
            
            this.setState(prevState => ({
                duplicates: prevState.duplicates.concat(node)
            }))
        }
    }

    
    render() {
        console.log("state: ", this.state)
        const elements = this.state.original.concat(this.state.duplicates)
        const graphStyles = { width: '100%', height: '800px' };

        return (
            <div>
                <ReactFlow  onNodeDragStart={this.onNodeDragStart} onNodeDragStop={this.onNodeDragStop}  style={graphStyles} elements={elements}></ReactFlow>
            </div>
        )
    }
}

The original node initially

After drag and drop to create a duplicate node at drop position. When I see the state of the component it still shows the position of original as position:{x:100, y:100}. But it is not at that position.

How to make original intact while creating a duplicate node? after dragging the original

Mounika Bathina
  • 123
  • 4
  • 13

1 Answers1

2

You have to add the code that will update the position in the state. By default this position is only used when creating new element but then it is not updated. You can solve this by changing your onNodeDragStop handler to something like this:

onNodeDragStop = (evt: MouseEvent, node: Node) => {
    if (!node.data.duplicate) {
        this.setState(prevState => ({
            original: prevState.original.map((n) => {
                if (n.id !== node.id) return node;

                return {
                    ...node,
                    position: {
                        x: node.position.x,
                        y: node.position.y
                    }
                }
            }),
            duplicates: [
                ...prevState.duplicates,
                {
                    ...node,
                    id: (this.lastId++).toString(10),
                    data: {
                        ...node.data,
                        duplicate: true,
                        label: "duplicate"
                    },
                }
            ]
        }))
    }
}

Also, I changed your code to not mutate the original node and instead return a new one with some properties changed.

Peter Adam
  • 21
  • 3
  • You are right! I did not realize you have originals in different array. I corrected my answer. – Peter Adam Aug 06 '20 at 09:51
  • have you executed this code? Because it is still not working for me. Sorry. – Mounika Bathina Aug 06 '20 at 10:25
  • No, because I don't have your whole code. Can you tell me what is the problem with it? Or can you maybe create snippet on https://codesandbox.io/ – Peter Adam Aug 06 '20 at 10:32
  • That is the whole code. I just wrote a single component. https://codesandbox.io/s/elastic-wood-6kqvm?file=/src/index.js – Mounika Bathina Aug 06 '20 at 11:16
  • There were a couple of issues, first, the project hove some problems with dependencies but when I downgraded version of `react-flow-renderer` to `5.1.0` it works. But this is only a sandbox issue. Next, there is invalid JSX in App.js, you have to close the `` tag. Also in `Platform.js` you are using typescript types (`evt: MouseEvent, node: Node`) for function arguments but this is in the javascript file. Finally, I just copied my code (without typescript types) to your example and it works as it should. Here is the working example https://codesandbox.io/s/eager-voice-3le8o. – Peter Adam Aug 06 '20 at 12:28
  • So I think your whole issue with my code was that you copied TypeScripts code into JavaScript project which is deferent programing language. – Peter Adam Aug 06 '20 at 12:29
  • Thank you so much. How to make original node not movable? I want it to stay in its initial position. – Mounika Bathina Aug 07 '20 at 06:08
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/219386/discussion-between-mounika-bathina-and-peter-adam). – Mounika Bathina Aug 07 '20 at 06:08