更新React中的d3元素? [英] Updating d3 elements in React?

查看:41
本文介绍了更新React中的d3元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据输入栏中的搜索输入来修改此气泡图.现在,我将所有d3代码放入Bubble.js中,然后在我的app.js中,我有一个searchinput元素将过滤要显示的数据,然后在我的Bubble状态下,将其数据设置为过滤后的数据(名为RoadmapData).但是,我的气泡图没有更新.实际上,每次我输入内容时,都会呈现另一个气泡图,因此,如果我输入3个字母,则会出现三个相同且未经过滤的气泡图.

I am trying to udpate this bubblechart base on my search input in an input bar. Right now, I put all the d3 code in a Bubble.js, and then in my app.js, I have a searchinput element that will filter my data to be displayed, and then in my Bubble's state, I set its data equal to the filtered data (named RoadmapData). However, my bubble chart is not updating. Actually, each time I type something in, another bubble chart renders, so if I type in 3 letters there are three same and unfiltered bubble charts.

这是我的代码:

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?预先感谢.

I am a beginner in d3, but I feel like the problem is either that I am using lifecycle methods wrong ( I used componentWillReceiveProps here, when I used componentMount() and typed in my search bar, nothing changed. Or maybe I shouldn't return this.node? Thanks in advance.

推荐答案

正在发生的事情是,每次重新渲染组件时, componentWillReceiveProps 函数都会创建可视化的新实例并添加通过对 node.append 的调用,将其添加到由React创建的< div> 节点.您可以通过 d3 remove()函数.

What's happening is that each time your component is re-rendered, the componentWillReceiveProps function is creating a new instance of the visualization and adding it to the <div> node created by React, via the calls to node.append. You can avoid this by removing the previously created instances via the d3 remove() function.

如果您愿意引入另一个库,则有一个名为 React Faux Dom ,这样您就可以避免所有React生命周期的问题,而只需照常执行 render()函数中的所有操作即可.可能会简化一些事情.

If you're willing to introduce another library, there's one called React Faux Dom that would allow you to avoid all the React lifecycle stuff and just do everything in the render() function as normal. It may simplify things a little.

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

You also mention that the chart is unfiltered every time - this is because you only assign the data prop to state in the constructor - this only runs once when your component is first created. In this case, it looks like you can safely remove this and read the data from this.props.RoadmapData every time (It doesn't appear that you are making any changes to the state inside the component).

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

You'd just need to add a line at the beginning of render() to get the data into the right format for d3, something like:

var roadmapDataForD3 = {子代:this.props.RoadmapData};

这篇关于更新React中的d3元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆