杭州电子商务研究院

基本 D3 和 React.js 集成

2020-10-22 08:00飞浪

介绍

D3.js 是一款出色的工具,可用于获取数据并根据该数据操作 DOM。但是,对于 React.js,框架使用所谓的虚拟 DOM 来表示 HTML 元素。对于熟悉 D3.js 但希望将其集成到 React.js 应用程序上下文中的开发人员来说,这可能会相当令人困惑。本指南将向您展示从 React.js 组件中调用 D3.js 的基础知识。

设置

首先创建一个用于容纳 D3.js 小部件的基本组件,名为MyD3Component:

      import React from 'react';
import * as d3 from "d3";

export default class MyD3Component extends React.Component {
  constructor(props) {
    super(props);

    this.myReference = React.createRef();
  }

  render() {
    return (
      <div ref={this.myReference}>
      </div>
    );
  }
}
    

除了包含 D3.js 库(import * as d3 from "d3" )之外,这里唯一奇怪的事情是在行this.myReference = React.createRef()中创建了一个引用。此值将作为虚拟 DOM 的引用锚点,D3.js 可以访问它,而不必使用 id 或 class 属性,因为我们实际上还没有渲染 HTML。此引用的集成是通过将其添加为此组件渲染的主要元素的ref属性的值来完成的。

接下来,创建另一个 React.js 组件作为你的“应用程序”,并将其命名为D3Example:

      import React from 'react';
import MyD3Component from './MyD3Component';

export default class D3Example extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    var data = [10, 20, 30];

    return (
      <div>
        <h1>D3 Example</h1>
        <MyD3Component
          data={data}
        />
      </div>
    );
  }
}
    

此组件最初所做的唯一一件事是拥有一些包含三个整数元素的虚拟数据。您将此数据作为MyD3Component的属性传递,可以通过其props以props.data的形式访问。

针对虚拟 DOM

要与虚拟 DOM 交互,D3.js 必须首先使用引用对象this.myReference对目标执行select()。为此,您可以创建一个表示此目标元素的变量,如下所示:

      var container = d3.select(this.myReference.current);
    

使用 D3.js 绘制数据

使用容器,您现在可以开始利用各种 D3.js 库调用来可视化数据。从简单的事情开始,为D3Example传递的props.data属性中的每个元素附加一个p标签。这可以通过以下代码完成:

      container
  .selectAll("p")
  .data(this.props.data)
  .enter()
  .append("p")
  .text(function(d) {
    return "Value is " + d;
  });
    

代码首先会选择容器中找到的所有p标签。然后,在调用enter()之前,使用.data(this.props.data)调用插入数据。链中的下一个调用将告诉 D3.js为this.props.data中找到的每个元素附加一个p标签。之后,.text()调用告诉 D3.js 向提取的每个数据元素添加文本。文本的呈现方式由传递给.text()的函数进行逻辑编程,该函数返回文本“Value is ”加上变量d表示的每次迭代的实际数据元素。

创建绘制函数

最后,您需要将所有内容包装在MyD3Component组件内定义的名为update的函数中:

      update() {
  var container = d3.select(this.myReference.current);

  container
    .selectAll("p")
    .data(this.props.data)
    .enter()
    .append("p")
    .text(function(d) {
      return "Value is " + d;
    });
}
    

在组件加载时,通过在componentDidMount生命周期方法中调用update()来调用它:

      componentDidMount() {
  this.update();
}
    

总体代码

您的最终代码应如下所示:

D3示例

      import React from 'react';
import MyD3Component from './MyD3Component';

export default class D3Example extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    var data = [10, 20, 30];

    return (
      <div>
        <h1>D3 Example</h1>
        <MyD3Component
          data={data}
        />
      </div>
    );
  }
}
    

我的D3组件

      import React from 'react';
import * as d3 from "d3";

export default class MyD3Component extends React.Component {
  constructor(props) {
    super(props);

    this.myReference = React.createRef();
  }

  componentDidMount() {
    this.update();
  }

  update() {
    var container = d3.select(this.myReference.current);

    container
      .selectAll("p")
      .data(this.props.data)
      .enter()
      .append("p")
      .text(function(d) {
        return "Value is " + d;
      });
  }

  render() {
    return (
      <div ref={this.myReference}>
      </div>
    );
  }
}
    

一旦安装到您的 HTML 文档,代码的输出应如下所示:

结论

由于使用了 React.js 中的虚拟 DOM,因此在 React.js 中调用 D3.js 需要一点时间来适应。一开始可能会相当混乱,但诀窍是遵循以下简单步骤:

  1. 使用React.createRef()创建一个引用对象,并通过ref属性将其作为值附加到目标元素。
  2. 使用引用的this.myReference.current属性并将其传递给 D3.js 的选择调用以创建一个容器。
  3. 在引用的容器内调用您的 D3.js 代码。
  4. 在 React.js 方法中,将 D3.js 逻辑包装在一个实用函数中,以便在需要使用新数据更新组件时可以轻松调用它。

通过扩展示例来调用 D3.js 的attr()函数来定义绘制 D3.js 可视化的区域的大小,并使用 D3.js 的style()调用在其周围绘制边框,从而亲自尝试一下。

曝光34946浏览1866