本文翻译自:
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 创建图表的更多相关文章

  1. 初探React与D3的结合-或许是visualization的新突破?

    自诞生之初截止目前(2016年初),React可以说是前端界最流行的话题,如果你还不知道React是何物,你就该需要充充电了. d3是由纽约时报工程师开源的一个绘制基于svg的数据可视化工具,是近几年 ...

  2. 使用D3绘制图表(7)--饼状图

    这次是绘制饼状图,也是这一次使用D3绘制图表的最后一篇,大家可以从其他地方深入学习D3绘制图表,也可以直接查看D3的API进行学习,本次绘制饼状图的数据跟之前的卸载数组里面的不一样,这一次是使用d3的 ...

  3. 使用D3制作图表(1)--画布绘制

    使用D3绘制图表可以使数据更加直观. 使用D3前要先加载D3库,这里有两种方式,一种是在线加载<script type="text/javascript" src=" ...

  4. Ember Charts – 基于 Ember & D3 的图表库

    Ember Charts 是一个基于 Ember.js 和 D3.js 的图表库.它包括时间序列.柱状图.饼图.点图,很容易扩展和修改.这些图表组件代表图表交互性和演示的最佳实践,是高度可定制和可扩展 ...

  5. python使用VBA:Excel创建图表(转)

    # -*- coding: utf-8 -*- """ Created on Thu Mar 06 11:22:03 2014 @author: Administrato ...

  6. Vue 爬坑之路(八)—— 使用 Echarts 创建图表

    在后台管理系统中,图表是一个很普遍的元素.目前常用的图标插件有 charts,  Echarts, highcharts.这次将介绍 Echarts 在 Vue 项目中的应用. 一.安装插件 使用 c ...

  7. C# 在PPT幻灯片中创建图表

    图表能够很直观的表现数据在某个时间段的变化趋势,或者呈现数据的整体和局部之间的相互关系,相较于大篇幅的文本数据,图表更增加了我们分析数据时选择的多样性,是我们挖掘数据背后潜在价值的一种更为有效地方式. ...

  8. Vue怎么使用Echarts创建图表

    摘要:在后台管理系统中,我们经常会遇到图表,比如说:柱形图,饼状图,折线图,雷达图等等,而用来写图表插件有很多,我这里主要介绍Echarts在项目里怎么使用,官网地址如下:https://echart ...

  9. react组件的创建

    最近项目接触react和rn,之前会一些vue和小程序,起初写react是很难受的,尤其是jsx的写法,不过2周过后感觉写起来有点舒服了... 目前react的组件一共有3种方式:React.crea ...

随机推荐

  1. Spring入门-----------------属性注入和对象注入

    属性注入即通过setter方法注入bean的属性或依赖对象. 属性注入使用<property>元素,使用name属性指定bean的属性的名称,value属性或<value>子节 ...

  2. STM32入门系列-库帮助文档使用

    在前面文件夹介绍时,提到了stm32f10x_stdperiph_lib_um.chm文件,此文件是库函数使用帮助文档,可以直接打开如下图. 因为STM32库函数非常多,我们不可能把所有的外设函数都记 ...

  3. MIPS学习笔记(一)

    写在前面 本文是根据"MIPS Assembly Language Programming CS50 Discussion and Project Book. Daniel J. Ellar ...

  4. Asp.Net Core学习笔记:入门篇

    Asp.Net Core 学习 基于.Net Core 2.2版本的学习笔记. 常识 像Django那样自动检查代码更新,自动重载服务器(太方便了) dotnet watch run 托管设置 设置项 ...

  5. 1到n整数中1出现的次数

    1到n整数中1出现的次数 题目描述 输入一个整数n, 求1~n这n个整数的十进制表示中1出现的次数. 例如, 输入12, 1~12这些整数中包含1的数字有1, 10, 11和12, 1一共出现了4次 ...

  6. Group指定的方式如下: @Test(groups = {"fast", "unit", "database" })

    Group指定的方式如下: @Test(groups = {"fast", "unit", "database" }) public voi ...

  7. first day for my bolg

    做为一名毕业不久的兢兢业业的前端小白,傻到一直用word做笔记,还有各种手抄(捂脸),下定决心以后改用博客,据说大神们都是这么做的!嘿嘿,先把各种笔记腾上来,内容实在惨不忍睹各种智商感人,希望不要有人 ...

  8. SpringBoot魔法堂:说说带智能提示的spring-boot-starter

    前言 前几个月和隔壁组的老王闲聊,他说项目的供应商离职率居高不下,最近还有开发刚接手ESB订阅发布接口才两周就提出离职,而他能做的就只有苦笑和默默地接过这个烂摊子了. 而然幸福的家庭总是相似的,而不幸 ...

  9. Scanner对象

    Scanner对象 通过Scanner类来获取用户的输入. 使用需导入 java.util.Scanner 包. 基本语法: Scanner s = new Scanner(System.in); n ...

  10. 各大数据库Java数据源参数

    Sybase: driver=com.sybase.jdbc3.jdbc.SybDriver url=jdbc:sybase:Tds:172.22.12.212:5000/ctninfo user=s ...