簡體   English   中英

如何使用react在d3強制布局中更新節點的數據

[英]How to update a data of a node in d3 force layout using react

我試圖使用react創建d3力布局圖,當我嘗試更新未反映在關聯數據中的節點數據時,我參考此https://codepen.io/vialito/pen/RympKp示例鏈接和節點與鏈接斷開連接,任何人都可以幫助我,這是我的以下代碼。

export default class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      addLinkArray: [],
      name: "",
      nodes:
        [
          {"name": "fruit", "id": 0},
          {"name": "apple", "id": 1},
          {"name": "orange", "id": 2},
          {"name": "banana", "id": 3}
        ],
      links:
        [
          {"source": 0, "target": 1, "id": 0},
          {"source": 0, "target": 2, "id": 1}
        ]
      }
    this.handleAddNode = this.handleAddNode.bind(this)
    this.addNode = this.addNode.bind(this)
    this.handleDelete = this.handleDelete.bind(this)
    this.handleUpdate = this.handleUpdate.bind(this)
    this.updateFlag = "";
  }

    componentDidMount() {

        const data = this.state;
            FORCE.initForce(data.nodes, data.links)
                FORCE.tick(this)
                FORCE.drag()
        console.log("after mount",this.state.links);
    }

    componentDidUpdate(prevProps, prevState) {
        if ((prevState.nodes !== this.state.nodes || prevState.links !== this.state.links)) {
            const data = this.state;
                console.log("comp update");
                console.log(this.state.nodes);
                console.log(this.state.links);

                FORCE.initForce(this.state.nodes,this.state.links);
                FORCE.tick(this);
                FORCE.drag();
                this.updateFlag = "";
        }

    }
    componentWillMount() {
      console.log("before mount",this.state.links);
    }

  handleAddNode(e) {
        this.setState({ [e.target.name]: e.target.value });
    }

  addNode(e) {
        e.preventDefault();
        this.setState(prevState => ({
            nodes: [...prevState.nodes, { name:this.state.name, id: prevState.nodes.length + 1, }], name: ''
        }));
        this.updateFlag = "created";
    }
    handleDelete() {
      this.setState(prevState=>({
        links:prevState.links.filter((node,i)=>{
          return i != 0
        }),
        nodes:prevState.nodes.filter((node,i)=>{
          return i != 1
        })
      }))
      this.updateFlag = "deleted";
    }
    handleUpdate() {
      const state2 = update(this.state.nodes, {0: {name: {$apply: function(x){ return "fruit2"}}}});

      this.setState({
        nodes : state2
      })
      console.log("this",this.state.links);
      //FORCE.initForce(this.state.nodes,this.state.links);

    }

    render() {
        var links = this.state.links.map( (link) => {
            return (
                <Link
                    key={link.id}
                    data={link}
                />);
        });
        var nodes = this.state.nodes.map( (node) => {
              return (
              <Node
                  data={node}
                  name={node.name}
                  key={node.id}
              />);
          });
        return (
          <div className="graph__container">
            <form className="form-addSystem" onSubmit={this.addNode.bind(this)}>
              <h4 className="form-addSystem__header">New Node</h4>
              <div className="form-addSystem__group">
                <input value={this.state.name} onChange={this.handleAddNode.bind(this)}
                  name="name"
                  className="form-addSystem__input"
                  id="name"
                  placeholder="Name"/>
                <label className="form-addSystem__label" htmlFor="title">Name</label>
              </div>
              <div className="form-addSystem__group">
                <input className="btnn" type="submit" value="add node" />
                <input className="btnn" onClick = {this.handleDelete} type="button" value="delete" />
                <input className="btnn" onClick = {this.handleUpdate} type="button" value="update" />
              </div>
            </form>
            <svg className="graph" width={FORCE.width} height={FORCE.height}>
                <g>
                    {links}
                </g>
                <g>
                    {nodes}
                </g>
            </svg>
          </div>
        );
    }
}

提前致謝

我看不到有關更新功能的任何詳細信息,但我懷疑它正在返回相同的數組對象。 因此,當您在componentDidUpdate中進行比較時,它不會觸發。

這是要嘗試的更改-

  handleUpdate() {
        const state2 =[...this.state.nodes]
        state2[0].name="fruit2";

        this.setState({
          nodes : state2
        })
        console.log("this",this.state.links);
        //FORCE.initForce(this.state.nodes,this.state.links);

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM