【译】用 React 和 D3 创建图表
本文翻译自:
https://dzone.com/articles/charts-with-modern-react-and-d3
本文将介绍如何利用 D3JS 和 ReactJS 来创建基础图表。
ReactJS 是一个用于制作可重用 Web 组件的前端 JavaScript 库。它的思路是(通过 React Native)将 Web 应用程序(以及移动应用程序)分解为较小的、独立的、可重用的组件。它使开发和维护中型到大型 Web 应用程序变得容易得多。
D3JS 是一个基于数据的 JavaScript 图形库。它可以帮助将数据绑定到 HTML 元素(SVG)并使用该数据操作 HTML 元素。你可以单独(不使用 ReactJS 或任何其他 Web 框架)用它来创建几乎所有任何数据可视化工具和仪表板。但是,如果你将其与 ReactJS 结合使用,那么就可以创建一个基于 Web 的现代化数据仪表板。
在本文中,我将展示如何使用 D3JS 和 ReactJS 的功能创建基本图表。后续,我将继续展示如何完全自定义图表并添加更多信息和交互内容。现在一切从简。让我们一起进入数据报告和可视化的世界吧。
在可视化数据之前,我们需要将数据传递给应用程序。现实生活中的应用程序,最有可能的是通过对服务器的 API 调用来完成此操作,从而向应用程序提供数据(通常为 JSON 或 XML 格式)。
这里我所举例的应用程序,数据存储在本地计算机上。我将使用 Node JS http 服务器来为其提供服务,以模拟真实的 API 调用。Http 服务器是一个用于设置服务器以提供静态文件的快速方法。我要做的就是创建一个文件夹(命名为 covid-data),存储数据文件(命名为 covid-data.csv),然后运行以下命令:
npx http-server --cors
注意:--cors 允许我们从(React)应用程序向同一台计算机上的服务器(http-server)发出请求。如果删除此标志,根据 CORS 策略,所有请求都将被拒绝。
现在我们已经运行了服务器并可以提供数据了。所以可以开始使用 React 和 D3 创建前端应用程序。
创建 React 应用程序的最佳方法是使用 Create React App:
npx create-react-app react-d3
完成此命令需要等待若干分钟。它将创建一个名为 react-d3 的新目录,并在其中创建一个基本的 React 应用程序。完成后,更改目录并启动应用程序:
Cd react-d3
Npm start
到这里,新的 React app 已经准备就绪,可以在端口3000上使用了。你只需启动浏览器,并确保通过访问以下链接来使其运行:
http://localhost:3000
你会看到React欢迎页面。
现在,我们需要做的就是启动项目。
首先,让我们尝试更改React的欢迎页面。打开 src / App.js,删除所有内容并将其替换为:
import React, { useEffect } from 'react';
import './App.css';
import draw from './draw'
function App() {
useEffect(() => {
draw()
})
return (
<div className="App">
<h1>D3 Simple Bar Chart</h1>
<div id="chart-container"></div>
</div>
);
}
export default App;
在 return 方法中,我们添加了一个id为“chart-component”的 div。我们将使用 D3 在此处添加图表。
我们还使用了一个名为“useEffect”的钩子,该钩子在类组件中基本上等效于“componentDidMount”和“componentDidUpdate”。在此钩子中,我们运行“draw”函数,这个函数会运行我们绘制图表所需的所有 d3 命令。当然,你也可以从 API 中获取数据,但是此处我们使用 D3 在 draw 函数中来完成数据处理。
到目前为止,React 已经搞定了我们创建图表所需要的基础设施。现在,让我们看看如何使用D3获取数据并绘制图表。
在 src 文件夹中创建一个文件,并将其命名为“ draw.js”,然后将以下代码放入其中:
import * as d3 from 'd3'
async function draw () {
const width = 800
const height = 500
const marginTop = 30
const marginRight = 30
const marginBottom = 30
const marginLeft = 50
const numOfCountries = 10
const title = "COVID-19 Death Count"
const svg = d3.select('#chart-container')
.append('svg')
.attr('width', width)
.attr('height', height)
.style('background-color', '#D3D3D3') svg.append('text')
.attr('x', (marginLeft + width + marginRight) / 2)
.attr('y', marginTop / 2)
.attr('dy', '0.33em')
.text(title)
.attr('text-anchor', 'end')
const dawData = await d3.csv('http://127.0.0.1:8080/covid-data.csv')
const data = dawData.filter(d => d.date === "2020-04-11" && d.location !== "World").sort((a, b) => b.new_deaths - a.new_deaths).filter((d, i) => i < numOfCountries).map(d => ({date: d.date, location: d.location, new_deaths: +d.new_deaths}))
console.log(data)
const xScale = d3.scaleBand()
.domain(data.map(d => d.location))
.range([marginLeft, width - marginRight])
.padding(0.3)
const xAxis = d3.axisBottom()
.scale(xScale) svg.append('g')
.attr('transform', 'translate(0,' + (height - marginBottom) + ')')
.call(xAxis) const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.new_deaths)])
.range([height - marginBottom, marginTop]) const yAxis = d3.axisLeft()
.scale(yScale) svg.append('g')
.attr('transform', 'translate(' + marginLeft + ', 0)')
.call(yAxis) svg
.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x', d => xScale(d.location))
.attr('y', d => yScale(d.new_deaths))
.attr('width', xScale.bandwidth())
.attr('height', d => height - marginBottom - yScale(d.new_deaths))
.attr('fill', 'yellow')
}
export default draw
我将逐行解释这些代码。
第1行导入所有的 d3 方法。
在第3行中,我们定义了一个 draw 函数。而且在后面的第67行,我们将导出此函数,以便可以在 App.js 文件中使用它。
在第5至12行中,我们定义了用于图表外观和功能的所有常量。
在14到18行中,我们选择id为“chart-component”(创建于“App.js”文件)的div,向其添加SVG元素,并设置其宽度,高度和背景颜色。
在第20至25行中,我们将标题添加到 SVG,并将其放置在合适的位置。
在第27-29行中,我们使用 d3.csv 方法通过 API 调用获取数据。然后,我们对其进行过滤,排序和重组,并将其记录到控制台,以便我们可以查看数据并确保其符合预期。稍后我们可能会在将其投入生产之前删除第29行(即使我们不这样做,在构建应用程序的生产版本时,React 也会自动删除所有 console.logs)。
在第31-34行中,我们使用d3的极为有用的 scale 方法(在本例中就是 scaleBand)来定义 X 比例尺,以便我们可以将数据点转换为图表上正确位置的实点。
随后,在第36-37行中,我们定义了一个轴,在第39-41行中,我们将该轴与 SVG 连接。在第43-52行,对 Y 轴执行完全相同的操作。
最后,在第54-63行中,我们选择 SVG(到目前为止是一个空集)上的所有 bar(矩形),将数据附加到 bar上,对于这些数据点,我们将一个新 bar 附加到 SVG。然后,我们调整每个 bar 的x,y,宽度,高度和填充颜色。
就是这样。这是用 D3 和 React 创建的非常简单的图表。当然它缺少许多功能,也不能交互,但是稍后我们可以添加上去。本文的目的是向大家展示使用 D3 和现代 React 创建简单图表是多么容易。
(完)

【译】用 React 和 D3 创建图表的更多相关文章
- 初探React与D3的结合-或许是visualization的新突破?
自诞生之初截止目前(2016年初),React可以说是前端界最流行的话题,如果你还不知道React是何物,你就该需要充充电了. d3是由纽约时报工程师开源的一个绘制基于svg的数据可视化工具,是近几年 ...
- 使用D3绘制图表(7)--饼状图
这次是绘制饼状图,也是这一次使用D3绘制图表的最后一篇,大家可以从其他地方深入学习D3绘制图表,也可以直接查看D3的API进行学习,本次绘制饼状图的数据跟之前的卸载数组里面的不一样,这一次是使用d3的 ...
- 使用D3制作图表(1)--画布绘制
使用D3绘制图表可以使数据更加直观. 使用D3前要先加载D3库,这里有两种方式,一种是在线加载<script type="text/javascript" src=" ...
- Ember Charts – 基于 Ember & D3 的图表库
Ember Charts 是一个基于 Ember.js 和 D3.js 的图表库.它包括时间序列.柱状图.饼图.点图,很容易扩展和修改.这些图表组件代表图表交互性和演示的最佳实践,是高度可定制和可扩展 ...
- python使用VBA:Excel创建图表(转)
# -*- coding: utf-8 -*- """ Created on Thu Mar 06 11:22:03 2014 @author: Administrato ...
- Vue 爬坑之路(八)—— 使用 Echarts 创建图表
在后台管理系统中,图表是一个很普遍的元素.目前常用的图标插件有 charts, Echarts, highcharts.这次将介绍 Echarts 在 Vue 项目中的应用. 一.安装插件 使用 c ...
- C# 在PPT幻灯片中创建图表
图表能够很直观的表现数据在某个时间段的变化趋势,或者呈现数据的整体和局部之间的相互关系,相较于大篇幅的文本数据,图表更增加了我们分析数据时选择的多样性,是我们挖掘数据背后潜在价值的一种更为有效地方式. ...
- Vue怎么使用Echarts创建图表
摘要:在后台管理系统中,我们经常会遇到图表,比如说:柱形图,饼状图,折线图,雷达图等等,而用来写图表插件有很多,我这里主要介绍Echarts在项目里怎么使用,官网地址如下:https://echart ...
- react组件的创建
最近项目接触react和rn,之前会一些vue和小程序,起初写react是很难受的,尤其是jsx的写法,不过2周过后感觉写起来有点舒服了... 目前react的组件一共有3种方式:React.crea ...
随机推荐
- 【实验课选题详解】用C语言实现万年历
题目要求 编程实现万年历,要求: 可根据用户输入或系统日期进行初始化,如果用户无输入则显示系统日期所在月份的月历,并突出显示当前日期: 可根据用户输入的日期查询,并显示查询结果所在月份的月历,突出显示 ...
- printk 流程分析
1. 概述 printk 用于在终端上打印内核想要输出的信息,平常我们较多使用的打印函数是 printf,两者名字虽然只有最后一个字母不同,且都是为了在终端上显示信息,但是它们的应用场景并不相同.pr ...
- 给Swagger换一套皮肤 Knife4j集成记录
Swagger有一套经典的UI,但是并不是很好用,之前有看到Knife4j,界面没管.功能完善,因此尝试集成. demo参考示例地址:knife4j-spring-boot-demo Knife4j前 ...
- Java学习的第五十三天
1.例9.5引用静态数据成员 public class Cjava { public static void main(String[]args) { Box b[] = {new Box(12,15 ...
- AWS SDK 使用说明
AWS 的Python SDK包名为 boto3, 可以使用命令pip install boto3安装使用 BOTO3中的基本概念 boto3提供了两个级别的接口来访问AWS服务:High Level ...
- shp文件转dwg并创建文本标注
不得不说,ArcGIS 和 CAD 之间的兼容性非常差,shapefile文件和dwg文件之间互相转换会丢失各种属性,但是很多时候他们之间的转换对我们来说是刚需.通常我们都是通过第三方软件(如FME) ...
- CF295C Greg and Friends
首先 我们考虑每次船来回运人时都可以看成一种dp状态 又因为人的体重只有50kg和100kg两种, 所以我们可以开一个三维数组dp[i][j][k],第1维表示在出发岸50kg有i个,第2维表示在出发 ...
- 【Kata Daily 190910】Who likes it?(谁点了赞?)
题目: Description: You probably know the "like" system from Facebook and other pages. People ...
- react 实现组件嵌套以及子组件与父组件之间的通信
当子组件触发onChange事件时,实际调用的是父组件中的handelSelect函数,通俗来说就是父组件通过属性handleSelect实现与子组件之间的通信. 父组件:SignupForm 子组件 ...
- CSS总结(一)
1 css常用的一些属性 color: 文字颜色(前景色) font-size: 文字大小 font-family: 字体,比如:微软雅黑, 黑体,宋体,仿宋体,"Times New Rom ...