iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
Modern Web

用React刻自己的投資Dashboard系列 第 5

用React刻自己的投資Dashboard Day5 - 多張圖表渲染(Rendering lists)

tags: 2021鐵人賽 React

上一篇只畫了一張圖表,投資怎麼可能只需要看一張圖呢?這邊就再加上兩張圖來看看吧!

更改資料放置位置

專案架構圖如下

這邊將靜態的資料放到src/data這個位置,與Charts分開來,感覺上會比較乾淨一些,其中有兩個json檔:

  • chart-collections 放一些要顯示在dashboard上面的圖表資訊,不包含數據,如下範例:
[
  {
    "id": 1,
    "series_id": "TREAST",
    "release_id": 20,
    "title": "美國聯準會持有美債金額",
    "document": "The total face value of U.S. Treasury securities held by the Federal Reserve. This total is broken out in the lines below. Purchases or sales of U.S. Treasury securities by the Federal Reserve Bank of New York (FRBNY) are made in the secondary market, or with various foreign official and international organizations that maintain accounts at the Federal Reserve. FRBNY's purchases or sales in the secondary market are conducted only through primary dealers.",
    "source": "FRED",
    "units": "百萬美元",
    "frequency": "weekly",
    "latest_released_date": "2021-08-06",
    "next_updated_date": "2021-08-13",
    "observation_start": "2021-01-01",
    "observation_end": "2021-08-10"
  },
  ...
]
  • observations 放相關圖表對應到的數據,如下範例:
    其中這些長得很奇怪的代號,是FRED官方定義的資料代號,從chart-collections.json中可以對照,"美國聯準會持有美債金額"對應到的series_id就是這個代號"TREAST"。
{
  "TREAST": [
    {
      "realtime_start": "2021-08-10",
      "realtime_end": "2021-08-10",
      "date": "2021-01-06",
      "value": "4699421.0"
    },
    {
      "realtime_start": "2021-08-10",
      "realtime_end": "2021-08-10",
      "date": "2021-01-13",
      "value": "4723733.0"
    },
    {
      "realtime_start": "2021-08-10",
      "realtime_end": "2021-08-10",
      "date": "2021-01-20",
      "value": "4743552.0"
    },
    ...
  ],
  "DGS10": [...],
  "A34HNO": [...]

在母元件引入資料

考量到之後會作篩選圖表的功能,因此選擇將資料從最上層的App.js載入,再透過React的props傳遞到子元件Charts,之後也可以傳遞到Selector給下拉式選單使用。

App.js

import './App.css';
import Navbar from './components/Navbar/Navbar';
import Selector from './components/Selector/Selector';
import Charts from './components/Charts/Charts';
// 引入資料
import chartCollections from './data/chart-collections.json';

function App() {
  // 定義資料Array,之後可以透過修改Array內容調整要呈現的圖表數量
  const charts = chartCollections;

  return (
    <div className="App">
      <Navbar />
      <Selector />
      <Charts chartCollections={charts} />
    </div>
  );
}

export default App;

子元件載入資料並繪製圖表

直接看程式碼說明似乎比較快,這邊就打在註解內:

Charts.js

import React from 'react';
import styles from './Chart.module.css';
import { Row, Col } from 'react-bootstrap';
import Highcharts from 'highcharts/highstock';
import HighchartsReact from 'highcharts-react-official';
// 載入數據
import observations from '../../data/observations.json';

// 建立fetchData函數以抓取每張圖表的數據
const fetchData = (series_id) => {
  let data = [];
  observations[series_id].forEach(ob => {
    data.push([new Date(ob.date).getTime(), Number(ob.value)]);
  });
  return data
};

const Charts = (props) => {
  // 將母元件傳進來的資料做一些處理
  let chartData = [];
  props.charts.forEach(chart => {
    chartData.push({
      id: chart.id,
      document: chart.document,
      source: chart.source,
      updated: chart.latest_released_date,
      options: {
        title: {
          text: chart.title
        },
        series: [
          {
            name: chart.title,
            // 抓取數據
            data: fetchData(chart.series_id)
          }
        ],
        xAxis: {
          type: "datetime",
          title: {
            text: 'Date'
          }
        }
      }
    })
  });

  // 下面使用Array的map方法,將資料帶入每個圖表
  return (
    <Row className={styles.charts}>
      {chartData.map((e) => (
        <Col sm={12} md={6} lg={4} className={styles.chartItem} key={e.id}>
          <div className={styles.chartFrame}>
            <HighchartsReact
              highcharts={Highcharts}
              constructorType={'stockChart'}
              options={e.options}
            />
            <div className={styles.chartInfo}>
              <p className={styles.source}>source: {e.source}</p>
              <p className={styles.date}>updated: {e.updated}</p>
            </div>
            <div>
              <p className={styles.document}>{e.document}</p>
            </div>
          </div>
        </Col>
      ))}
    </Row>
  )
};

export default Charts;

Rendering lists注意事項

這邊要注意的是React在rendering lists的時候,要給每個元素一個key,如同上面的key={e.id},目的是讓React可以認得這些元素,將來在做新增/修改/刪除...之類的,才知道要去更動哪個元素。

數據抓取方式

另外上面有一個fetchData函數,目前是從json檔去讀資料,為了模仿之後是打API去取資料,這邊才需要先寫成一個arrow function。

成果顯示

程式寫好之後,重新執行後就顯示出來啦:

小結

本篇先將多筆靜態資料一次渲染出來,接下來還有幾項事情要做,依序是:

  • 將圖表小區塊另外拉成Charts的子元件,程式碼看起來會更簡潔一些。
  • 數據來源改為串接API,應該會用到React的useEffect/useCallback...等等Hook。
  • 完成下拉式選單功能,讓使用者可以篩選要看的圖。
  • Scroll down動態載入資料。

有好多想法想要實作,就一步步的來吧~


上一篇
用React刻自己的投資Dashboard Day4 - highcharts製作線圖
下一篇
用React刻自己的投資Dashboard Day6 - 建立圖表區元件,串接API取得數據
系列文
用React刻自己的投資Dashboard30

尚未有邦友留言

立即登入留言