Rechartsの面グラフを使う

## 概要
Rechartsを使う機会があったので、備忘録がてらQiitaに残すことにしました。
今回使ったのは面グラフだけなので、悪しからず🙏

### サクッと紹介
Reactでグラフを表示したい場合に使われるチャートライブラリです。
Reactならではの再利用性があります。

公式サイト → [Recharts](http://recharts.org/en-US)

折れ線グラフ、棒グラフ等もあり、ミックスして表示させることもできるようです。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327745/d7af1b46-2967-e4fe-7618-a613d8baaf7c.png)

上の画像はこちらのサイト「[Choosing a data visualization library for React](https://hackernoon.com/choosing-a-data-visualization-library-for-react-444263a41f98)」から引用しました。
こちらの筆者は[Nivo](https://nivo.rocks/)に決めたようですが、私はRechartsを少し突っ込んでいくことにします。

### 面グラフ　使い方
今回は面グラフの実装が必要だったため、面グラフにフォーカスした話をします。
公式サイトのこちらにあるようなグラフです。
  ↓
[SimpleAreaChart](http://recharts.org/en-US/examples/SimpleAreaChart)
[StackedAreaChart](http://recharts.org/en-US/examples/StackedAreaChart)

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327745/f9fab149-6a80-255b-2f99-4b93a8dc4ea7.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327745/14460ace-42e4-e767-ce01-3f2d3cb1d552.png)

[Getting Started](http://recharts.org/en-US/guide/getting-started)を進めながら実装することにします。

（インストールはこちらから → [Installation](http://recharts.org/en-US/guide/installation)）

```shell
$ npm install recharts
```

### グラフをカスタマイズ
Examplesから、使いたいグラフのサンプルコードをそのまま持ってくるところから始めます。

#### 出来上がり

グラフ用のAtomコンポーネント、`<Graph />`は下のような記述になりました。

```javascript
import React from 'react'
import moment from 'moment'
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts'

const SimpleAreaChart = (props) => {
  const { data, dataKey, color } = props

  return (
    <AreaChart width={500} height={300} data={data}>
      <CartesianGrid strokeDasharray="3 3" />
      <XAxis
        dataKey="date"
        interval={0}
        tickFormatter={(tickItem) => moment(tickItem).format('MM/DD')}
      />
      <YAxis />
      <Tooltip />
      <Area dataKey={dataKey} stroke={color} fill={color} />
    </AreaChart>
  )
}

export default SimpleAreaChart
```

* `<Graph />`コンポーネント共通化しておくと、グラフを複数個表示する時使い回せます！
* `<Graph />`に渡すpropsとして、①データ、②表示するキー名、③グラフの色を渡すようにしています。
* `<CartesianGrid />`に指定している`strokeDasharray`の数字を大きくすればするほど、点線の粒度が荒くなります。
* `<Tooltip />` を入れると、ホバーした時データの詳細が表示するツールチップが表示されるようになります。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327745/c6b6890c-9409-a643-f5d0-213320d7b203.png)


また、私の場合、X軸を日付に指定したかったので、表示用にフォーマットを整えています。
データは下のようなオブジェクトを作っています。

```javascript
const data = [
  { date: '2019-07-01', apple: 400, banana: 240, orange: 240 },
  { date: '2019-07-02', apple: 300, banana: 139, orange: 221 },
  { date: '2019-07-03', apple: 200, banana: 980, orange: 229 },
  { date: '2019-07-04', apple: 278, banana: 390, orange: 200 },
  { date: '2019-07-05', apple: 189, banana: 480, orange: 218 },
  { date: '2019-07-06', apple: 239, banana: 380, orange: 250 },
  { date: '2019-07-07', apple: 349, banana: 430, orange: 210 },
]
```

日付を「07/01」のように表示したかったので、`<XAxis />`に`tickFormatter`を指定しています。
```
<XAxis tickFormatter={(tickItem) => moment(tickItem).format('MM/DD')} />
```

X軸の表示変換にはこちらのページ → [XAxis](http://recharts.org/en-US/api/XAxis)
オプションをざっと説明します。（tickは「目盛り」という意味です！）

|  オプション  |  説明  |
| ---- | :--- |
|  tick  | デフォルトtrue。falseにすると横軸ラベルが消える |
|  tickSize  | デフォルト6。X軸の下に伸びる、ラベル名と線の間の長さが変えられる |
|  interval  | 0に設定すると、すべての目盛りが表示される。 `preserveStart`、`preserveEnd`、または`preserveStartEnd`を設定すると、表示または非表示にする目盛が自動的に計算される。 |
|  tickFormatter  | 目盛り成形用のフォーマッタ関数が指定できる |


大体これで完成なのですが、最後にレスポンシブさせて横幅を可変にしたいと思います。
Rechartsには`<ResponsiveContainer />`が用意されています。なので、importに`ResponsiveContainer`を追加し、`<AreaChart />`をラップしてあげます。
この時、グラフをラップしてあるdivなどのコンテナのcssに、高さを指定することが必須です。

```javascript
import {
  ResponsiveContainer,
  ・・・
} from 'recharts'

const SimpleAreaChart = (props) => {
  ・・・
  return (
    <div style={{ width: '100%', height: '300px' }}>
      <ResponsiveContainer>
        <AreaChart width={500} height={300} data={data}>
          ・・・
        </AreaChart>
      </ResponsiveContainer>
    </div>
  )
}
```

これで横幅可変のグラフが完成しました！

### 値をトータルするグラフ
各グラフの値を積み重ねて表示するグラフが作りたかったので、[StackedAreaChart](http://recharts.org/en-US/examples/StackedAreaChart)を用いることにします。
表示する方法は「`<Area />`タグに同一の`stackId`を指定する」です。
そうすると単純にグラフが重なると思います。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327745/9b42e90b-c42e-caa9-86d3-266ae8fde341.png)

上の例では左上が各グラフのトータルを表す面グラフです。
type属性に`"monotone"`をしていると急勾配の時カクカクしてしまうみたいですが、
typeは種類豊富に取り揃えられてるので色々試して見てください！
公式 → [Areaのtypeについて](http://recharts.org/en-US/api/Area#type)

Areaタグに`fillOpacity`をつけてもかっこよくなるかもしれません！

## 最終的なソースコード
### Atom/グラフコンポーネント

```javascript
import moment from 'moment'
import React from 'react'
import {
  ResponsiveContainer,
  AreaChart,
  CartesianGrid,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts'

const SimpleAreaChart = (props) => {
  const { data, children } = props

  return (
    <ResponsiveContainer>
      <AreaChart width={500} height={300} margin={{ right: 30 }} data={data}>
        <CartesianGrid strokeDasharray="3 3" />
        <XAxis
          dataKey="date"
          interval={0}
          tickFormatter={(tickItem) => moment(tickItem).format('MM/DD')}
        />
        <YAxis />
        <Tooltip />
        {children}
      </AreaChart>
    </ResponsiveContainer>
  )
}

export default SimpleAreaChart
```

### Organisms/グラフ群

```javascript
import React from 'react'
import SimpleAreaChart from 'components/atoms/SimpleAreaChart'
import { Area } from 'recharts'

const data = [
  { date: '2019-07-01', apple: 100, banana: 10, orange: 40 },
  { date: '2019-07-02', apple: 80, banana: 20, orange: 60 },
  { date: '2019-07-03', apple: 90, banana: 10, orange: 50 },
  { date: '2019-07-04', apple: 0, banana: 20, orange: 80 },
  { date: '2019-07-05', apple: 30, banana: 40, orange: 70 },
  { date: '2019-07-06', apple: 80, banana: 90, orange: 100 },
  { date: '2019-07-07', apple: 20, banana: 90, orange: 100 },
]

const GraphLists = () => {
  return (
    <div css={wrapper}>
      <div css={graphItem}>
        <h5>フルーツ</h5>
        <SimpleAreaChart data={data}>
          <Area
            type="natural"
            stackId="fruit"
            dataKey="apple"
            stroke="#f00"
            fill="#f00"
          />
          <Area
            type="natural"
            stackId="fruit"
            dataKey="banana"
            stroke="#0f0"
            fill="#0f0"
          />
          <Area
            type="natural"
            stackId="fruit"
            dataKey="orange"
            stroke="#00f"
            fill="#00f"
          />
        </SimpleAreaChart>
      </div>
      <div css={graphItem}>
        <h5>りんご</h5>
        <SimpleAreaChart data={data}>
          <Area type="natural" dataKey="apple" stroke="#f00" fill="#f00" />
        </SimpleAreaChart>
      </div>
      <div css={graphItem}>
        <h5>バナナ</h5>
        <SimpleAreaChart data={data}>
          <Area type="natural" dataKey="banana" stroke="#0f0" fill="#0f0" />
        </SimpleAreaChart>
      </div>
      <div css={graphItem}>
        <h5>オレンジ</h5>
        <SimpleAreaChart data={data}>
          <Area type="natural" dataKey="orange" stroke="#00f" fill="#00f" />
        </SimpleAreaChart>
      </div>
    </div>
  )
}

export default GraphLists
```


## 終わりに
グラフの可視化、超楽しい！😆😆😆数字入れるだけでめっちゃキレイな面グラフが出来上がるのに感動です✨
Rechartsだけでなく、他のチャート系でもドキュメント豊富、且つgitHubのスター数が多いライブラリが色々あったので、今後も開拓してみることにします。👀