【译】用 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 ...
随机推荐
- 联考day7 C. 树和森林 树形DP
题目描述 样例 样例输入 8 5 BBWWWBBW 1 2 2 3 4 5 6 7 7 8 样例输出 84 2 1 4 样例解释 分析 首先,我们要预处理出一个点到该联通块内所有点的距离之和 \(f\ ...
- 《Clojure编程》笔记 第16章 Clojure与web
目录 背景简述 第16章 Clojure与web 16.1 术语 16.2 Clojure栈 16.3 基石:Ring 16.3.1 请求与应答 16.3.2 适配函数 16.3.3 处理函数 16. ...
- python爬虫06取当当网 Top 500 本五星好评书籍
主要思路 使用 page 变量来实现翻页 我们使用 requests 请求当当网 然后将返回的 HTML 进行正则解析 由于我们暂时还没学到数据库 所以解析完之后就把内容存到文件中 def main( ...
- mysql实现当前行的值累加上一行的值
数据库钱包表有日期.收入.支出三个字段.用mysql语句计算每日余额,得如下结果 select m.*, @total :=@total + 收入 - 支出 as 钱包余额 ( select * fr ...
- 对于STM32F103的USART的通讯调试
USART:(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步串行接收/发送器USART是一个全双工通用同步/异步串行收发 ...
- php post请求https
<?php $url = 'https://www.xxx.com'; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); c ...
- Java 中数组转换为 List
目录 1 - int 型数组转换为 List 2 - List 转换为 int 型数组 3 - String 型数组转换为 List 4 - List 转换为 String 型数组 版权声明 开发中经 ...
- 你的旧版本 App 为何运行在 iPhone 12 上没有异常?
背景 当我在 10月14日 iPhone 12 系列发布直播,看到 iPhone 12 系列的分辨率后,我注意到这些分辨率是全新的时,我立即在群里吐槽:又需要适配一波了.我只是以为宽高变化会导致字号变 ...
- 【转】volatile和synchronized的区别
volatile和synchronized的区别 volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取: synchronized则是锁定当前变量,只有当前 ...
- Mybatis执行SQL的流程
前篇:Mybatis初始化过程 SqlSession : SqlSession是一个接口,它有两个实现类:DefaultSqlSession (默认)和 SqlSessionManager (弃用,不 ...