用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动态载入资料。

有好多想法想要实作,就一步步的来吧~


<<:  Day 07 - 导流专家Route 53

>>:  Day 20 : 模型优化 - 训练後量化 Post Training Quantization

LeetCode解题 Day07

206. Reverse Linked List https://leetcode.com/prob...

尝试的结果

我在网路上查资料时,看到有人写了关於不覆盖有资料的方法,不过档案是txt档的写入,我不知道如果换成x...

Tableau Server 使用-管理跟大规模自助式分析并无矛盾(课程推荐)

你觉得Tableau Server让你最困扰的点是什麽? 没有管理,就无法成就自助分析 你也跟第一位...

python 奇偶数个数计算

QC+ 程序语言 Python 3 _ 408 奇偶数个数计算 说明: 请撰写一程序,让使用者输入十...

[Day 27] Edge Impulse + BLE Sense实现影像分类(上)

在前面章节已介绍如何让Arduino Nano 33 BLE Sense(以下简称BLE Sense...