数据可视化是指使用图表、图形等可视化对象以更清晰、更有效的方式进行数据通信的技术。
在web上,有许多库可用来可视化数据,但最突出的是D3js库。它已经成为数据可视化的事实,并赢得了许多开发人员的信任。
React是一个被许多开发人员使用的库。在本文中,我们将了解如何使用React和D3创建既可重用又美观的组件。
首先,让我们简要分析一下这些库。
React
React是一个用于构建用户界面的JavaScript库。它使创建可重用组件变得容易,这些组件可以组合在一起形成更复杂的组件。
这些组件能够自己维护它们的状态。
D3
D3.js是一个基于数据操作文档的JavaScript库。它使用HTML、CSS和SVG使数据栩栩如生。
D3试图提供一种基于数据的高效操作数据的方法,而不是提供框架来完成所有可能的功能。
D3是快速的,支持大数据集和动态行为的动画和交互。
下面就来看看如何一起使用这两个库来创建动态数据可视化组件。
安装React
安装react最简单的方法是使用react团队的create-react-app模板。
在本地机器上全局安装,以便可以重用,在终端上运行以下命令:
npm install -g create-react-app
接下来我们使用create-react-app模板创建一个新的app
create-react-app react-d3
下面进入新工程的目录
cd react-d3
安装D3
您可以使用CDN或通过NPM安装将D3库添加到应用程序
在本例中,我们使用NPM来安装:
npm install d3
现在准备工作做完了,我们可以在React中使用D3进行数据可视化开发了。
要在默认浏览器上预览创建的应用程序,请运行以下代码:
npm start
使用D3创建一个条形图(chart)
使用你喜欢的编辑器(我用vscode)打开工程,并打开文件 src/App.js
.
这是当前在浏览器中呈现的组件。我们需要删除render()方法的内容,替换成我们自己的内容。
在src
目录中创建一个BarChart.js的文件,用来创建我们的条形图。
在文件中加入以下代码:
import React, {Component} from 'react';
import * as d3 from "d3";
class BarChart extends Component {
}
export default BarChart;
我们将使用ComponentDidMount
生命周期方法在BarChart组件已被装载到DOM中时显示条形图。
在BarChart组件中添加以下内容:
class BarChart extends Component {
componentDidMount() {
this.drawChart();
}
}
我们将在drawChart
方法中完成D3的绘制工作。
通常,在不使用React的情况下使用D3时,您不必将D3代码放入方法中,但这在React中非常重要,可以确保只在组件被挂载到DOM上时才显示图表
接下来,我们创建drawChart方法:
drawChart() {
const data = [12, 5, 6, 6, 9, 10];
const svg = d3.select("body").append("svg").attr("width", 700).attr("height", 300);
}
这个方法做了些什么呢?
首先,我们定义了一个变量data
,它包含了我们想要可视化的数据。
其次,我们使用D3的方法定义了一个svg。我们使用SVG是因为它是可伸缩的,也就是说,无论屏幕有多大,或者您放大多少来查看数据,它都不会显示为像素化。
d3.select()用来选择文档中的HTML元素。它选择与传递参数相匹配的第一个元素,并为其创建一个节点。
在本例中,我们传递了body
元素,稍后将对其进行更改,以使组件更加可重用。
append()
方法的作用是:将一个HTML节点附加到所选项上,并返回该节点的句柄。
attr
方法用于向元素添加属性。这可以是您通常添加到HTML元素中的任何属性,如class
、height
、width
或fill
。
接着我们向body元素添加了一个svg元素,高:700,宽:300。
在我们创建的SVG变量下面,添加以下代码:
svg.selectAll("rect").data(data).enter().append("rect")
与select
方法一样,selectAll()
选择与传递给它的参数匹配的元素。而selectAll()
选择的所有与参数匹配的元素,而不仅仅是第一个。
data()
方法用于将数据附加到所选HTML元素。
大多数情况下,这些元素不会被找到,因为大多数可视化处理的是动态数据,而且几乎不可能估计要表示的数据量。
enter()
方法将我们从瓶颈中解救出来,因为它与append
方法一起使用来创建丢失的节点,并且仍然可视化数据。
到目前为止,我们已经为每个数据点创建了节点。剩下的就是让它可见了。
为了使其可见,我们需要为每个数据集创建一个栏,设置一个宽度并动态更新每个栏的高度。
attr
方法允许我们使用回调函数来处理动态数据:
selection.attr("property", (d, i) => {})
其中d为数点值,i为数据在数组中的索引。
首先,我们需要将每个数据点设置在条形图的x轴和y轴上的特定点上
首先,我们需要将每个数据点设置在条形图的x轴和y轴上的特定点上。我们使用“x”和“y”属性来实现这一点,其中“x”表示棒沿x轴(水平方向)的位置,“y”表示棒沿y轴的位置。
另外,我们需要设置每个数据点的宽度和高度。每个数据点的宽度是恒定的,因为条形图的宽度是相同的。
另一方面,高度取决于每个数据点的值。我们必须使用回调函数使条形图显示每个数据点的值。
我们将SVG变量修改为:
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", (d, i) => i * 70)
.attr("y", 0)
.attr("width", 25)
.attr("height", (d, i) => d)
.attr("fill", "green");
对于“x”,数组中数据点的每个索引都乘以一个常数整数70,使每个条的位置移动70。
y有一个常数y,我们很快就会改变。
宽度也有一个常数值65,小于图表中每个元素的位置,从而在每个元素之间创建一个空间。
条的高度取决于数据集中每个条目的值。
使用它,我们创建了一个条形图。然而,我们有两个问题:
- 图表中的条形图很小
- 图表也是倒过来的
为了解决上述问题,我们将每个数据乘以一个常量,比如10,以在不影响数据的情况下增加每个bar的大小:
.attr("height", (d, i) => d * 10)
接下来,我们将解决柱状图被倒置的问题,但在此之前,我们先来理解为什么图表会被倒置。
SVG的位置从上到下开始,因此使用y属性0将每个条放到SVG元素的顶部边缘。
为了解决这个问题,我们用SVG元素的高度减去每个条的高度:
.attr("y", (d, i) => h - 10 * d)
其中(10 * d)是我们之前计算得到的高度。
综合起来,BarChart
组件将是:
class BarChart extends Component {
componentDidMount() {
this.drawChart();
}
drawChart() {
const data = [12, 5, 6, 6, 9, 10];
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
.style("margin-left", 100);
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", (d, i) => i * 70)
.attr("y", (d, i) => h - 10 * d)
.attr("width", 65)
.attr("height", (d, i) => d * 10)
.attr("fill", "green")
}
render(){
return
}
}
export default BarChart;
现在我们有了一个基本的条形图。我们再多做一点,添加标签。
向条形图添加标签
为了添加标签,我们在drawChart函数中添加了以下代码:
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text((d) => d)
.attr("x", (d, i) => i * 70)
.attr("y", (d, i) => h - (10 * d) - 3)
这与我们对这些条所做的类似,但是这次,text
被追加。
条形图应该是这样的:
构建可重用的柱状图
React的一个重要部分是使组件可重用。
为此,我们需要删除提供的数据,然后通过props将其传递给组件。
SVG的宽度和高度也将通过props传递:
const data = [12, 5, 6, 6, 9, 10];
变成:
const data = this.props.data;
宽度和高度属性由:
const svg = d3.select("body").append("svg").attr("width", 700).attr("height", 300);
变成:
const svg = d3.select("body").append("svg")
.attr("width", this.props.width)
.attr("height", this.props.height);
在App.js文件中,我们现在可以使用组件并从父组件传递我们想要的数据:
class App extends Component {
state = {
data: [12, 5, 6, 6, 9, 10],
width: 700,
height: 500,
id: root
}
render() {
return (
);
}
}
这样,我们可以在我们的React应用程序中任意地方重用条形图。
感谢!!!!!!!
翻译自:https://blog.logrocket.com/data-visualization-in-react-using-react-d3-c35835af16d0