【问题标题】:Updating d3 elements in React?在 React 中更新 d3 元素?
【发布时间】:2019-06-04 19:53:50
【问题描述】:

我正在尝试根据我在输入栏中的搜索输入来更新此气泡图。现在,我将所有 d3 代码放在 Bubble.js 中,然后在我的 app.js 中,我有一个 searchinput 元素,它将过滤要显示的数据,然后在我的 Bubble 状态下,我将其数据设置为等于过滤后的数据(名为 RoadmapData)。但是,我的气泡图没有更新。 实际上,每次我输入内容时,都会呈现另一个气泡图,因此如果我输入 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() 并在我的搜索栏中输入时,没有任何改变。或者我不应该返回 this.node?提前谢谢。

【问题讨论】:

    标签: javascript reactjs d3.js


    【解决方案1】:

    发生的情况是,每次重新渲染您的组件时,componentWillReceiveProps 函数都会创建一个新的可视化实例,并通过对 node.append 的调用将其添加到由 React 创建的 &lt;div&gt; 节点。您可以通过 d3 remove() function 删除以前创建的实例来避免这种情况。

    如果你愿意引入另一个库,有一个名为 React Faux Dom 的库,它可以让你避免所有 React 生命周期的东西,只需像往常一样在 render() 函数中执行所有操作。它可能会简化一些事情。

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

    您只需在 render() 的开头添加一行,即可将数据转换为 d3 的正确格式,例如:

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

    【讨论】:

    • 嘿,非常感谢,我想这确实是正确的答案。但我想如果我只做this.props.RoadmapData,它不起作用,因为我缺少“孩子”部分,你对此有什么建议吗?
    • 您可以在render() 函数的开头使用children 构建您需要的对象,然后继续将该新变量传递给d3 命令。那应该这样做。 (类似于var roadmapDataForD3 = { children: this.props.RoadmapData };
    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    相关资源
    最近更新 更多