iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 19
0
Modern Web

資料視覺化!D3入門到實戰系列 第 19

Day19 實戰!Github Heat Map 產生器_在React中使用D3

  • 分享至 

  • xImage
  •  

上一份專案我們選用的前端框架是vue,我有提到使用vue的原因是環境設定比較簡單,用官方的cli工具就能夠建立一個完整的專案架構。相較於vue來說,react就沒有那麼方便使用了,在開始寫code之前可能要整理一下檔案結構,然後該裝的套件裝一裝(如node-sass),如果要用redux的話又更麻煩了,連dev tool的環境都要自己設定。所以這邊簡單帶一下如果要在react專案當中使用d3該怎麼寫比較好~

小提醒:我在這邊都會使用function component,所以會大量使用react hook的東西,其實概念很簡單,這邊放上文件https://reactjs.org/docs/hooks-intro.html

專案架構

在使用create-react-app建好專案的時候,你會發現他把所有檔案都放在src的資料夾內,看了實在是不舒服XD,我在這邊介紹一下我習慣的整理方式:

  1. 建立一個components的資料夾,把component放進裡面,而一個component也許會有container、component本體、style以及只有這個才會用到的圖片或是js檔案,包成一個資料夾:
src
|- components
        |- A
            |- AContainer.js
            |- A.js
            |- A.module.scss
            |- img
            |- someFunc.js
        |- B
  1. 一些共用的style及圖片則會另外新建一個assets來放,並從index.js或App.js引入。

加入d3

因為react檔案所有東西都會寫在一起,不像vue那樣template跟function分得好好的,所以我會建議把d3畫圖的function寫在另一個檔案裡面再import進來,否則畫圖的程式碼那麼長,放在component裡面看起來會很亂不好維護。

drawMap.js

import * as d3 from 'd3';

const drawMap = (id) => {
  d3
    .select(`#${id}`)
    .append('svg')
    .attr('width', 100)
    .attr('height', 100);
}

export default drawMap;

chart.js

import React, { useState, useEffect, useCallback } from 'react';
import shortid from 'shortid';

import drawMap from './drawMap';

const HeatMap = (props) => {
  //React hook的用法,等同於以前class component的this.state,在vue當中就是data
  const [id] = useState(shortid.generate());
  
  //定義一個畫圖的function,使用useCallback讓id有變動時這個function才會被更新,等同於以前class component裡面定義的this.handleDrawMap(),在vue中則是methods
  const handleDrawMap = useCallback(() => {
    drawMap(id);
  }, [id]);

  // 當handleDrawMap有變動時才會執行,而handleDrawMap只有id有變動的時候才會變動,因此目前看起來只有componentDidMount的時候才會重新畫圖
  useEffect(() => {
    handleDrawMap()
  }, [handleDrawMap]);

  return <div id={id}></div>;
};

export default React.memo(HeatMap);

上一篇
Day18 實戰!Github Heat Map 產生器_專案說明
下一篇
Day20 實戰!Github Heat Map 產生器_Heat Map實作(1)
系列文
資料視覺化!D3入門到實戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言