代码之家  ›  专栏  ›  技术社区  ›  Acy

更新React中的d3元素?

  •  0
  • Acy  · 技术社区  · 7 年前

    我试图根据输入栏中的搜索输入来提取这个bubblechart。现在,我将所有d3代码放在一个Bubble.js中,然后在我的app.js中,我有一个searchinput元素,它将过滤要显示的数据,然后在我的Bubble状态下,我将其数据设置为与过滤后的数据相等的数据(名为roaddata)。然而,我的气泡图并没有更新。 事实上,每次我输入一些东西,就会出现另一个气泡图,所以如果我输入3个字母,就会有三个相同的未过滤气泡图 .

    这是我现在的代码:

    import React, { Component } from "react";
    import * as d3 from "d3";
    
    class Bubble extends Component {
      constructor(props) {
        super(props);
        this.state = {
          dataset: { children: this.props.RoadmapData }
        };
      }
    
      componentWillReceiveProps(nextProps) {
        var diameter = 600;
    var color = d3.scaleOrdinal(d3.schemeCategory10);
    
    var bubble = d3
      .pack(this.state.dataset)
      .size([diameter, diameter])
      .padding(1.5);
    
    var svg = d3
      .select("body")
      .append("svg")
      .attr("width", diameter)
      .attr("height", diameter)
      .attr("class", "bubble");
    
    var nodes = d3.hierarchy(this.state.dataset).sum(function(d) {
      return d.Count;
    });
    
    var node = svg
      .selectAll(".node")
      .data(bubble(nodes).descendants())
      .enter()
      .filter(function(d) {
        return !d.children;
      })
      .append("g")
      .attr("class", "node")
      .attr("transform", function(d) {
        return "translate(" + d.x + "," + d.y + ")";
      });
    node.append("title").text(function(d) {
      return d.Name + ": " + d.Count;
    });
    
    node
      .append("circle")
      .attr("r", function(d) {
        return d.r;
      })
      .style("fill", function(d, i) {
        return color(i);
      });
    
    node
      .append("text")
      .attr("dy", ".2em")
      .style("text-anchor", "middle")
      .text(function(d) {
        return d.data.Name.substring(0, d.r / 3);
      })
      .attr("font-family", "sans-serif")
      .attr("font-size", function(d) {
        return d.r / 5;
      })
      .attr("fill", "white");
    
    node
      .append("text")
      .attr("dy", "1.3em")
      .style("text-anchor", "middle")
      .text(function(d) {
        return d.data.Count;
      })
      .attr("font-family", "Gill Sans", "Gill Sans MT")
      .attr("font-size", function(d) {
        return d.r / 5;
      })
      .attr("fill", "white");
      }
    
      render() {
    return <div>{this.node}</div>;
      }
    }
    
    export default Bubble;
    

    我是d3的初学者,但我觉得问题可能是我使用的生命周期方法错误(我在这里使用了componentWillReceiveProps,当我使用componentMount()并在搜索栏中键入时,没有任何更改。或者我不应该返回此.node?提前感谢。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Matt Holland    7 年前

    发生的情况是,每次重新渲染组件时 componentWillReceiveProps 函数正在创建可视化的新实例并将其添加到 <div> React创建的节点,通过调用 node.append . 您可以通过通过删除先前创建的实例来避免这种情况 d3 remove() function .

    如果你愿意介绍另一个图书馆,有一个叫做 React Faux Dom render() 正常工作。它可能会简化一些事情。

    您还提到图表每次都未过滤-这是因为您只将数据属性分配给 state 在构造函数中-这仅在首次创建组件时运行一次。在这种情况下,看起来您可以安全地删除它并从中读取数据 this.props.RoadmapData 每次(您似乎没有对组件内部的状态进行任何更改)。

    您只需要在开始处添加一行 render() 要将数据转换为d3的正确格式,请执行以下操作:

    var roadmapDataForD3 = { children: this.props.RoadmapData };