本文翻譯自:
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 創建簡單圖表是多么容易。
(完)