20190710のReactに関する記事は9件です。

React Native(Expo)でiOSアプリ「寝過ごし・乗り過ごし防止」をApp Storeに公開した件

はじめに

どんなアプリを作ったの?

「寝過ごし・乗り過ごし防止」アプリ

降車する駅を登録しておくと、
電車などの乗物で近づいたタイミングで教えてくれるアプリ
サラリーマンや電車通勤の学生向け

いらすとや_3.png

つまり?⇒
* 降りる駅を気にしなくて済む!
* 寝ててもOK!漫画やスマホに熱中しててもOK!
* 音楽でアナウンスが聞こえなくてもOK!

いらすとや_2.png

アプリの使い方

  1. 自宅や会社・学校の最寄り駅を検索して駅を登録
  2. 登録した駅に一定距離に近づくと通知してくれる
  3. 必要に応じて通知時間を設定

   

本記事の目的

宣伝目的だよ。 備忘録やExpoを使用してみた感想など。
これから使ってみたいって人に興味を持っていただけたら嬉しい。
ある程度ダウンロードされたらどれくらい需要があるのかも書きたいと思います。

話すこと

  • 開発当初から申請が通るまでの手順
  • Expo(React-native)でどんなライブラリを使ったか
  • どんな機能を使ったか
  • 連携した外部機能
  • 苦労したこと
  • したいけどできなかったこと
  • これからしたいこと
  • 収入・ダウンロード数 ※いつかは掲載します

話さないこと

  • Expoなどの具体的な使い方
  • App Storeの申請方法

開発当初から申請が通るまでの手順

  • 持ち物
    • imac
    • iphone6S (Expo Clientをインストール)
  • 環境・ツール
    • Expo Snack
      • 最初のプログラム開発。簡単な実装はこれで確認したほうが楽。
    • vscode
      • 「Expo Snack」から途中で交代。中盤~終盤はこちらで実装。
    • Github(smartGitで管理)
      • ソースコード管理といったらコレでしょ。
    • xcode(Application loader)
      • これがないとApp Storeにビルドファイルをアップロードできないのです。
    • iphone simulator
      • App Store公開時にipadサイズ、iphoneXRサイズのスクリーンショットが必要。
    • (iphone:MandalArtアプリ)
      • アプリのアイデアだし、メモなどに。
  1. Expoに登録してExpo Snackで画面周りや簡易機能などをゴリゴリに実装(2019/03~04)
  2. 簡単に実機・Emu接続ができるので検査 ※バグがあったら「1」に戻る(2019/03~04)
  3. ある程度できたらvscodeでビルド(2019/04~06)
  4. 「3」でビルドしたipaファイルをxcodeでアップロード(2019/05~06)
  5. App Storeに申請 ※リジェクト(申請却下)されたら「3」に戻る(2019/05~06)
  6. 目出度く公開完了(2019/06/20)

開発時にどんなライブラリを使ったか

ええい、package.jsonを見たほうがはやい!

package.json
"axios": "0.19.0",
"ex-react-native-i18n": "0.0.5",
"expo": "^33.0.0",
"expo-ads-admob": "^5.0.1",
"expo-localization": "^5.0.1",
"expo-location": "^5.0.1",
"expo-permissions": "^5.0.1",
"expo-task-manager": "^5.0.1",
"react": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-33.0.0.tar.gz",
"react-native-app-link": "1.0.0",
"react-native-elements": "1.1.0",
"react-native-maps": "^0.24.2",
"react-native-modal-datetime-picker": "7.4.2",
"react-native-swipeout": "2.3.6",
"react-native-vector-icons": "6.5.0",
"react-navigation": "3.11.0",
"react-redux": "7.0.3",
"redux": "^4.0.0-0",
"sentry-expo": "^1.13.0"

どんな機能を使ったか

  • axios
    • API実行
  • ex-react-native-i18n
    • メッセージ、名称などを簡易に多言語化
  • expo
    • Expoのメイン機能
  • expo-ads-admob
    • google-admobの広告
  • expo-location
  • expo-task-manager
    • 位置情報取得・geolocation機能
  • expo-permissions
    • iphoneの通知・位置情報取得権限
  • react-native-app-link
    • 無料版アプリから有料版アプリへのリンク飛ばし
  • react-native-elements
    • ヘッダーなどExpoの素材でないもの系
  • react-native-maps
    • 地図、本アプリではGoogle Mapを使用
  • react-native-modal-datetime-picker
    • 時刻picker
  • react-native-swipeout
    • リストを横スワイプ(削除)できる
  • react-native-vector-icons
    • アイコン系、豊富で見てみると面白い
  • react-navigation
    • 画面遷移
  • react-redux
  • redux
    • reduxによるステータスの保存。ただしアプリ履歴を消したら、ステータスも消えてしまうので、AsyncStorageにも設定していた。
  • sentry-expo
    • バグ検出用

連携した外部機能

  • Google API ※一定以上で有料
    • Geolocationや位置情報を取得時に使用
    • 駅名検索で使用(place API)
  • google-Admob
    • 広告。Expoだとgoogle-Admobの広告機能が簡単に実装できます。
  • sentry-expo
    • sentryというExpoで管理できない発生したエラーもこちらで出力、感知してくれます。終盤のAppleリジェクト時にお世話になりました。

苦労したこと

  • Apple様によるリジェクト地獄。合計20回ほど。
    • Expoでは動く、自分の実機でも動く。でもApple様は動かない。
    • Emulatorで確認⇒実機で確認⇒sentryで確認しました。
      • こっちでは動くのに、こっちでは動かないってことが多々あった。
    • App Store ConnectよりdSYMでcrash-reportを確認してみる。
      • Google Mapの地図を使う場合は『app.json』に"config":{"googleMapsApiKey":"XXXXXXXXXXXXX"}を記載する必要がある。
    • その他の指摘
      • 通知(notofication)を使用する場合は「Permissions.getAsync( Permissions.NOTIFICATIONS」を使ってね
      • 位置情報取得を使用する場合は「Permissions.askAsync(Permissions.LOCATION)」を使ってね
      • 位置情報取得を使用する場合は『app.json』に"infoPlist": {"NSLocationWhenInUseUsageDescription":"AAA","UIBackgroundModes":["location"]}を記載する必要がある
    • テンプレのような指摘内容、そして意味不明なクラッシュレポート
    • 英語
      • Google翻訳
  • Expo Clietで途中からgeolocationがテストできなくなった。(実機では動くから心配しないで)
  • iMacのバージョンが古くて、xcodeが最新じゃない
    • ビルドしたIPAファイルを実機に入れることができなかった。 それでも申請は通った。
  • デザイン
    • デザインは色々な人にみてもらった。最初は明るめな色にしていたが、暗めがいい、類似色に統一したほうがいいと意見をたくさんもらった。
    • 奥が深い...(ちなみに、アプリアイコンはデザイナーに作ってもらいました)

いらすとや_4.png

したいけどできなかったこと

  • 無料版と有料版は分けたくなかった(アプリ内課金を使いたかった)
    • デタッチを使えばできるんだけど、xcodeを使っての管理になるのが嫌だったので止めた
  • バックグラウンドでの通知時にバイブレーションや音声機能を使用
    • 無理だった。バックグラウンドではアプリの機能の一部が使えなくなった。

これからしたいこと

  • Android対応
    • Expoってマルチプラットフォーム開発が強みなんです。だからAndoridもすぐビルドはできたのですが、iosとは違ってできること、できないことがあります。
  • 海外の言語対応
    • App Storeの申請では国ごとに説明を変えることができる。まずはアメリカなどの英語圏を網羅して分母を増やしていきたい。
  • デザイン、要望の対応
    • 画面の機能以外に構想はしていたが、蛇足な気がしたので排除した。しかし、今後も色々と要望は出てくると思うので多数の意見は組んでいきたい。
  • マーケティング
    • まずは無料版が売れたらいいなぁと感じています。そのために、SNSやアプリのレビューサイトなどを色々駆使して世に知らしめていきたいと思っています。

終わり

Expoはクラウドの開発環境なのですが、PCのスペックが低かったこともありとても使いやすかったです。実機と簡単に接続ができるところもGoo!
会社の業務でreactを触っていたので、開発しやすかったのはありますが、初めてのアプリ開発はけっこう楽しかったです。

いらすとや_6.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

redux-form (6) - ユーザ登録

redux-form (1) - Simple Form Example
redux-form (2) - Synchronous Validation Example
redux-form (3) - Field-Level Validation Example
redux-form (4) - Submit Validation Example
redux-form (5) - Initialize From State
redux-form (6) - ユーザ登録


ReactでForm componentを作るときに、とても便利なredux-formの説明です。

redux-formの概説についてはまず以下の記事を参考にしてください。

redux-form (1) - Simple Form Example

今回は少し実用を意識して、ユーザ登録を実装します。UIコンポネントを作成するためにantdを使います。
React UI library の antd について (1) - Button

ユーザ登録

画面イメージ

画面イメージです。antdを使っているので、簡単にアイコンで装飾できます。

image.png

環境設定

まずは開発環境を構築します。

yarn create react-app antd-demo
cd antd-demo
yarn add redux react-redux redux-form redux-logger antd

念のため、package.jsonを掲載しておきます。

package.json
{
  "name": "antd-demo",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "antd": "^3.20.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-redux": "^7.1.0",
    "react-scripts": "3.0.1",
    "redux": "^4.0.1",
    "redux-form": "^8.2.4",
    "redux-logger": "^3.0.6"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

ソースコード

ユーザの配列を保持する Redux state を定義します。ユーザを追加するだけの簡単なものにします。

src/reducers
const users = (state = [], action) => {
  switch (action.type) {
    case 'ADD_USER': // *** userを追加
      return [
        ...state,    // *** 分割代入、stateに追加
        {
          email: action.user.email,
          name: action.user.name,
          password: action.user.password
        }
      ]
    default:
      return state
  }
}

export default users

これもユーザを追加するactionだけを定義します。

src/actions.js
export const addUser = user => ({
  type: 'ADD_USER',
  user: user
})

index.jsです。ユーザ登録のみの簡単な機能しかありませんが、redux-loggerredux-formを組み合わせているので、少し複雑かもしれません。

src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { createStore, combineReducers, applyMiddleware } from 'redux'
import { reducer as reduxFormReducer } from 'redux-form'
import logger from 'redux-logger'
import Register from './Register'
import users from './reducers'
import { addUser } from './actions'

const dest = document.getElementById('root')
const reducer = combineReducers({
  users,
  form: reduxFormReducer
})
const store = createStore(
    reducer,
    applyMiddleware(logger)
)

const showResults = values =>
  new Promise(resolve => {
    setTimeout(() => {
      // simulate server latency
      console.log(`submitted:${JSON.stringify(values, null, 2)}`)
      store.dispatch(addUser(values));
      resolve()
    }, 500)
  })

// redux-formを使っているのでProviderは必要
let render = () => {
  ReactDOM.hydrate(
    <Provider store={store}>
      <Register onSubmit={showResults} />
    </Provider>,
    dest
  )
}

render()

ユーザ登録画面の構築には、antdとredux-formを組み合わせて作っているので、少し複雑です。

  • Register componentの大枠はantdFormを利用しています。
  • Formの子要素にはredux-formField を利用しています。
  • 更にFieldのcomponent属性にantdInput(で作られたcomponent)を利用しています。

antdとredux-formを組み合わせについては、以下の記事も参照ください。
React UI library の antd について (3) - redux-form

redux-formによるvalidateはシンプルなのでいいですね。

src/Register.js
import React from 'react';
import PropTypes from 'prop-types';
import { Form, Icon, Button } from 'antd';
import { Field, reduxForm } from 'redux-form';
import renderInput from './input';
import 'antd/dist/antd.css';

import './style.css';

const RegisterForm = props => {
  const { handleSubmit, pristine, submitting, message } = props;

  return (
    <Form onSubmit={handleSubmit} className="form-register-containers">
        <h1 className="center">
          ユーザ登録
        </h1>
        <Field
          name="email"
          hasFeedback
          component={renderInput}
          disabled={submitting}
          label="メールアドレス"
          placeholder="メールアドレス"
          prefix={<Icon type="mail" style={{ color: 'rgba(0,0,0,.25)' }} />}
        />
        <Field
          hasFeedback
          type="password"
          name="password"
          component={renderInput}
          disabled={submitting}
          label="パスワード"
          placeholder="パスワード"
          prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
        />
        <Field
          hasFeedback
          type="password"
          name="confirmPassword"
          component={renderInput}
          disabled={submitting}
          label="確認用パスワード"
          placeholder="確認用パスワード"
          prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
        />
        <Field
          hasFeedback
          name="name"
          component={renderInput}
          disabled={submitting}
          label="お名前"
          placeholder="お名前"
          prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
        />
        <Form.Item className="center">
          <Button
            type="primary"
            htmlType="submit"
            className="btn-submit"
            disabled={pristine || submitting}
          >
            ユーザ登録
          </Button>
        </Form.Item>
        {!!message && <p className="caption-invalid">{message}</p>}
    </Form>
  );
};

// redux-formのvalidate
const validate = values => {
  const errors = {};
  if (!values.email) {
    errors.email = 'Required';
  } else if (
    !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)
  ) {
    errors.email = 'Invalid email address';
  }

  if (!values.password) {
    errors.password = "Password can't be blank";
  }

  if (!values.confirmPassword) {
    errors.confirmPassword = "Confirm password can't be blank";
  }

  if (
    values.password &&
    values.confirmPassword &&
    values.password !== values.confirmPassword
  ) {
    errors.confirmPassword = "Confirm password didn't match";
  }

  if (!values.name) {
    errors.name = "Name can't be blank";
  }

  return errors;
};

RegisterForm.propTypes = {
  pristine: PropTypes.bool,
  message: PropTypes.string,
  submitting: PropTypes.bool,
  handleSubmit: PropTypes.func,
};

export default reduxForm({
  form: 'register-form',
  validate,
})(RegisterForm);

以下がrenderInput componentのソースです。propsを展開して、inputやrestを取り出していることに注目してください。そのままInput componentに展開されます。特に(1)input object (redux-form) はvalueを含んでおり、(2)Input (antd component) のvalue属性の値としてそのまま適用されます。このvalueはactionによりRedux stateにbindされています。またrestにはprefixが含まれており、そのままアイコン情報が展開されます。
(1) Redux-form Fieldのinput object
(2) Antd Input component

src/input.js
import React from 'react';
import { Form, Input } from 'antd';

const newComponent = props => {
  const { input, meta, hasFeedback, label, ...rest } = props;
  const hasError = meta.touched && meta.invalid;

  return (
    <Form.Item
      label={label}
      help={hasError && meta.error}
      hasFeedback={hasFeedback && hasError}
      validateStatus={hasError ? 'error' : 'success'}
    >
      <Input {...input} {...rest} />
    </Form.Item>
  );
};

export default newComponent;

実行結果

redux-formのエラーメッセージ
image.png

登録時の redux-logger のログ
image.png

今回は以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Material ui のlabelの色を変えたい!buttonのlabelの色を変えたい!という時の小ワザ

material ui のFormControlLabelの色をデフォルトから別の色に変えたいという時や、
MuiButtonのlabelの色を変えたいという時があるかと思うんですが、
そういう場合に使えるワザを紹介します。

環境:
 react@16.8.6
 @material-ui/core@4.1.1

FormControlLabelのlabelの色を変える

material ui のデフォルトはこうです
スクリーンショット 2019-07-10 10.34.05.png

デフォルトのコード
<FormControlLabel
        control={
          <Checkbox checked={state.checkedA} onChange={handleChange('checkedA')} value="checkedA" />
        }
        label="Secondary"
      />


Secondaryという文字を青に変えたいとき

<FormControlLabel
        control={
          <Checkbox checked={state.checkedA} onChange={handleChange('checkedA')} value="checkedA" />
        }
        label={
          <span style={{ color: "blue" }}>
            Secondary
          </span>
        }
      />

label= に中括弧つけて、Secondaryをspanで挟んで色指定してあげれば、

スクリーンショット 2019-07-10 10.42.55.png

色が青に変わりました!

MuiButtonのlabelの色を変えたい!

ボタンを実装して、ボタン自体の色は変えられたけど、どうしてもlabelの色が変わんない・・・
こんなときないですか?

スクリーンショット 2019-07-10 10.53.06.png
このボタンのlabelをどうしても白にしたい!

まずはmaterial uiのファイルを作る

theme.jsを作り、createMuiThemeをimportする

アプリのデベロッパーツールでボタンのlabelのところをクリックすると
下図のようにでるので、theme.jsでoverridesの中に書いていく
スクリーンショット 2019-07-10 18.13.37.png

theme.js
import { createMuiTheme } from "@material-ui/core/styles";

export const theme = createMuiTheme({
overrides: {
    MuiButton: {
      label: {
        color: "white",
      },
    },
  },
});

↓白に変わりました!

スクリーンショット 2019-07-10 11.58.44.png


このやり方はスタイルを無理やり変えてる感あるので、
もっといいやり方があれば教えてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VueやReactでコンポーネントやモジュールの依存関係を把握する

はじめに

なんかこのコンポーネント誰に依存されているかわかんないの、変更した時不安(´;ω;`)
って声があったので、コンポーネント間の依存関係を出すツールを調べて使ってみました。
結果かなり良かったです。

madge

DEMO

DEMO

概要

madgeはtsconfigやwebpackの設定を与えて、何をさせるのか指定します。
例えば、依存グラフをsvgで出力させたり、vg形式で出力させたりできます。
また、循環依存があるファイルリスト、依存されているのが1つ以上あるリスト、逆にどれにも依存されていないリストを出したりできます。
cliで軽くやるのからnodeでフルコントロールもできるのでかなり細かい事ができ、例えばこのモジュールはここからしか依存させないなどの設定をCIやエディターに簡単に組み込ませたりできます。(例:クリーンアーキテクチャーが持つポリシーの1つである、レイヤーを通り越して依存するの禁止等が簡単に実現できます。

React

一応jsxはtypescriptが標準サポートしているので、jsx間の依存は簡単に見れる。
graph.jpg

ちょっとボリュームのあるこのリポジトリの依存!
も出してみる。
graph.jpg
見やすくてかなり良い感じだと思います!

Vue

https://github.com/pahen/madge/issues/122
vueファイル間の依存を出したかったんですが、それはまだできないっぽいです(´;ω;`)

dependency-cruiser

dependency-cruiserは標準でvueの依存グラフを出せますし、madgeと同じように循環依存検知等色々できます。
また、出力はdot言語なので、dot言語のレイアウトエンジンを調整すればいろいろできます。

こちらのリポジトリをサンプルに依存グラフを出します。
https://github.com/kahirokunn/book-management

これがサンプルです
CreateBookForm_dependencygraph.jpg

特定コンポーネント単位なら割といけますね。

ちなみにデフォルト設定で全部出すとめっちゃカオスです
叩いたコマンドはこれです

$ depcruise --webpack-config ./node_modules/@vue/cli-service/webpack.config --exclude "^node_modules" --output-type dot src | dot -T jpg > dependencygraph.jpg && open ./dependencygraph.jpg

dependencygraph.jpg

レイアウトエンジンに関してはこちらの記事を見ていただきたいです
http://melborne.github.io/2013/04/02/graphviz-layouts/

デフォルトレイアウトエンジンはdotで、あまり見やすくないですね。。。
自分の好みはneatoです。
こんな感じになります。

dependencygraph.jpg

まぁカオスには変わりないですが、まだまし、、、?なのかなって(´;ω;`)

まとめ

現状の依存グラフのエコシステムだとこの辺までできるようです。
もしもっとこういうのもあってこうできるよ!とか、いろいろありましたら教えていただけると幸いです。

参考資料

https://qiita.com/rubytomato@github/items/51779135bc4b77c8c20d#edge
http://melborne.github.io/2013/04/02/graphviz-layouts

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rechartsの面グラフを使う

概要

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

サクッと紹介

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

公式サイト → Recharts

折れ線グラフ、棒グラフ等もあり、ミックスして表示させることもできるようです。
1.png

上の画像はこちらのサイト「Choosing a data visualization library for React」から引用しました。
こちらの筆者はNivoに決めたようですが、私はRechartsを少し突っ込んでいくことにします。

面グラフ 使い方

今回は面グラフの実装が必要だったため、面グラフにフォーカスした話をします。
公式サイトのこちらにあるようなグラフです。

SimpleAreaChart
StackedAreaChart

2.png
3.png

Getting Startedを進めながら実装することにします。

(インストールはこちらから → Installation

$ npm install recharts

グラフをカスタマイズ

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

出来上がり

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

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

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

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
オプションをざっと説明します。(tickは「目盛り」という意味です!)

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

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

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を用いることにします。
表示する方法は「<Area />タグに同一のstackIdを指定する」です。
そうすると単純にグラフが重なると思います。

5.png

上の例では左上が各グラフのトータルを表す面グラフです。
type属性に"monotone"をしていると急勾配の時カクカクしてしまうみたいですが、
typeは種類豊富に取り揃えられてるので色々試して見てください!
公式 → Areaのtypeについて

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

最終的なソースコード

Atom/グラフコンポーネント

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/グラフ群

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のスター数が多いライブラリが色々あったので、今後も開拓してみることにします。?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ReactNativeでの開発に向けたロードマップ

現在フリーランスとして活動している大学生のものです。

WP案件やLP案件で普通のバイトくらいは稼いでいます。
できることはHTMLcssでのコーディング、及びJSで少々アニメーションを付けられる程度です。

このたび諸事情でReactNativeでの開発に向けて勉強することになりました。
時間がありません。

僕の現状からReactNativeで開発できるようになるための、ロードマップを教えてください。

心より、よろしくお願いいたします!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerHubで公開されているコンテナが安全か確かめてみた結果【人気のコンテナ上位800個】

はじめに

Docker Hubに公開されているイメージはどの程度安全なのか、 Dockle starsTrivy stars を利用して検証しました。
検証結果は、 https://containers.goodwith.tech/ に公開しています。

screencast24.gif

結論

基本的にどのコンテナにも脆弱性はある!
人気が高いコンテナ/最近ビルドされているコンテナでも関係ない!

ただ、Docker公式が用意しているコンテナは今のところ大丈夫。
より詳しいことを知りたい人は 操作方法 を見て、 https://containers.goodwith.tech/ を操作してみてください。

操作方法

page.png

① ソートやフィルタが簡単にできます

header-2.png

※ Scoreは脆弱性のCVSSスコアなどを元にした参考値です。指標を一つに統一したかったので作りました。
ガチ勢の方々、怒らないでください & よりよい指標をつくるためのアドバイスをください。

② Dockle, Trivy というカラムを選択すると、JSON形式で詳細な情報が表示されます

clickable-2.png

③ JSONのロードが遅いときは「JSON Detail」のリンクからダウンロードできます

jsondetail-2.png

※ netlifyを利用してるんですが、特に大きいJSONファイルの取得が遅いので、解決方法を知りたいです

何がチェックできるの?

CISベンチマークに沿っているかチェックできます。CIS(The Center for Internet Security)のセキュリティ専門家たちが発行している資料です。

slide17

簡単に言うと、Dockleの列ではイメージの設計が正しくされているか、Trivyの列では脆弱性のあるパッケージが使われていないかをチェックできます。

その他にも、パスワードが設定されていないユーザのチェックなど、Linuxの基礎的なセキュリティもチェックします。
original-checkpoint-comparison.png

ただし、すべてのコンテナで警告が出てしまうので、「latestタグはやめよう」「Content Trustを有効にしよう」の2項目は無視しています。

データの作り方

過去に記事にした Dockle starsTrivy stars を利用しています。
対象のコンテナイメージに対してそれぞれスキャンしていき、結果を集計しました。なお800個のコンテナを平行処理して1時間掛かりませんでした。

なお、私はDockleの作者で、Trivyのメインコミッタの一人です。GitHub Starが増えると喜びます。

フロントエンドやホスト環境は?

reactnetlify.png

メインで使っているライブラリは以下のものです。
Docker Meetup Tokyo #31のLTに間に合わせるべく、画面のベース作成1日というギリギリのスケジュールだったためCreate React Appを利用しました。

├── public : JSONや画像など
├── src : ソースコード
└── yarn.lock

フォルダ構成は現在このようになっており、すべてnetlifyでホストされています。
ただ、ファイルサイズが大きくなるとnetlifyだと極端に遅くなります。
特に脆弱性の数が多いJSONデータのロードで顕著です。解決策があれば教えてください。

脆弱性対策はどうすればいい?

ここや、この記事の後半でお伝えしたとおり、どのように向き合うかは、そのサービスの用途や求めるレベルによります。

ただ、Trivyで検出された脆弱性については、新しいOSにして新しいバージョンのパッケージを入れたら脆弱性は減るので、公開されているDockerfileを元に自らの手で書き直すことをおすすめします。

脆弱性についてより詳しいことが気になった人は、私も参加しているプロジェクト Vulsのチームが主催する 「既知の脆弱性はこう捌け!」系の勉強会に参加すると、体系的に学ぶ事ができます。

最後に

最初に、Docker公式が用意しているイメージが今のところ大丈夫と伝えました。
しかし、いつ脆弱性が入るのかはわからないので、ビルドごとにイメージのチェックすることをおすすめします。実例として、今年の5月まで公式が用意したAlpine LinuxのイメージにRootユーザのパスワードが設定されていないという脆弱性がありました。

ローカルビルドの際に、すでにあるイメージを毎回参照していて、過去の脆弱性をそのまま使い続けている状況もありえます。ローカルでイメージを作成している人/コンテナのイメージをキャッシュから作成されている方は、特に一度スキャンすることをおすすめします。

なお、今後も https://containers.goodwith.tech/ に、ユーザーの入力したイメージ名からスキャンをするなど、機能追加していく予定です。 フッターにシェアボタン付けたので、シェアお願いします?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerHubで公開されているコンテナが安全か確かめてみた【人気のコンテナ上位800個!】

はじめに

Docker Hubに公開されているイメージはどの程度安全なのか、 Dockle starsTrivy stars を利用して検証しました。
検証結果は、 https://containers.goodwith.tech/ に公開しています。

page.png

結論

基本的にどのコンテナにも脆弱性はある!
人気が高いコンテナ/最近ビルドされているコンテナでも関係ない!

ただ、Docker公式が用意しているコンテナは今のところ大丈夫。
より詳しいことを知りたい人は 操作方法 を見て、 https://containers.goodwith.tech/ を操作してみてください。

操作方法

① ソートやフィルタが簡単にできます

header-2.png

※ Scoreは脆弱性のCVSSスコアなどを元にした参考値です。指標を一つに統一したかったので作りました。
ガチ勢の方々、怒らないでください & よりよい指標をつくるためのアドバイスをください。

② Dockle, Trivy というカラムを選択すると、JSON形式で詳細な情報が表示されます

clickable-2.png

③ JSONのロードが遅いときは「JSON Detail」のリンクからダウンロードできます

jsondetail-2.png

※ netlifyを利用してるんですが、特に大きいJSONファイルの取得が遅いので、解決方法を知りたいです

何がチェックできるの?

CISベンチマークに沿っているかチェックできます。CIS(The Center for Internet Security)のセキュリティ専門家たちが発行している資料です。

slide17

簡単に言うと、Dockleの列ではイメージの設計が正しくされているか、Trivyの列では脆弱性のあるパッケージが使われていないかをチェックできます。

その他にも、パスワードが設定されていないユーザのチェックなど、Linuxの基礎的なセキュリティもチェックします。
original-checkpoint-comparison.png

ただし、すべてのコンテナで警告が出てしまうので、「latestタグはやめよう」「Content Trustを有効にしよう」の2項目は無視しています。

データの作り方

過去に記事にした Dockle starsTrivy stars を利用しています。
対象のコンテナイメージに対してそれぞれスキャンしていき、結果を集計しました。なお800個のコンテナを平行処理して1時間掛かりませんでした。

なお、私はDockleの作者で、Trivyのメインコミッタの一人です。GitHub Starが増えると喜びます。

フロントエンドやホスト環境は?

reactnetlify.png

メインで使っているライブラリは以下のものです。
Docker Meetup Tokyo #31のLTに間に合わせるべく、画面のベース作成1日というギリギリのスケジュールだったためCreate React Appを利用しました。

├── public : JSONや画像など
├── src : ソースコード
└── yarn.lock

フォルダ構成は現在このようになっており、すべてnetlifyでホストされています。
ただ、ファイルサイズが大きくなるとnetlifyだと極端に遅くなります。
特に脆弱性の数が多いJSONデータのロードで顕著です。解決策があれば教えてください。

脆弱性対策はどうすればいい?

ここや、この記事の後半でお伝えしたとおり、どのように向き合うかは、そのサービスの用途や求めるレベルによります。

ただ、Trivyで検出された脆弱性については、新しいOSにして新しいバージョンのパッケージを入れたら脆弱性は減るので、公開されているDockerfileを元に自らの手で書き直すことをおすすめします。

脆弱性についてより詳しいことが気になった人は、私も参加しているプロジェクト Vulsのチームが主催する 「既知の脆弱性はこう捌け!」系の勉強会に参加すると、体系的に学ぶ事ができます。

最後に

最初に、Docker公式が用意しているイメージが今のところ大丈夫と伝えました。
しかし、いつ脆弱性が入るのかはわからないので、ビルドごとにイメージのチェックすることをおすすめします。実例として、今年の5月まで公式が用意したAlpine LinuxのイメージにRootユーザのパスワードが設定されていないという脆弱性がありました。

ローカルビルドの際に、すでにあるイメージを毎回参照していて、過去の脆弱性をそのまま使い続けている状況もありえます。ローカルでイメージを作成している人/コンテナのイメージをキャッシュから作成されている方は、特に一度スキャンすることをおすすめします。

なお、今後も https://containers.goodwith.tech/ に、ユーザーの入力したイメージ名からスキャンをするなど、機能追加していく予定です。 フッターにシェアボタン付けたので、シェアお願いします?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerHubで公開されているコンテナが安全か確かめてみた結果【人気のコンテナ上位800個!】

はじめに

Docker Hubに公開されているイメージはどの程度安全なのか、 Dockle starsTrivy stars を利用して検証しました。
検証結果は、 https://containers.goodwith.tech/ に公開しています。

screencast24.gif

結論

基本的にどのコンテナにも脆弱性はある!
人気が高いコンテナ/最近ビルドされているコンテナでも関係ない!

ただ、Docker公式が用意しているコンテナは今のところ大丈夫。
より詳しいことを知りたい人は 操作方法 を見て、 https://containers.goodwith.tech/ を操作してみてください。

操作方法

page.png

① ソートやフィルタが簡単にできます

header-2.png

※ Scoreは脆弱性のCVSSスコアなどを元にした参考値です。指標を一つに統一したかったので作りました。
ガチ勢の方々、怒らないでください & よりよい指標をつくるためのアドバイスをください。

② Dockle, Trivy というカラムを選択すると、JSON形式で詳細な情報が表示されます

clickable-2.png

③ JSONのロードが遅いときは「JSON Detail」のリンクからダウンロードできます

jsondetail-2.png

※ netlifyを利用してるんですが、特に大きいJSONファイルの取得が遅いので、解決方法を知りたいです

何がチェックできるの?

CISベンチマークに沿っているかチェックできます。CIS(The Center for Internet Security)のセキュリティ専門家たちが発行している資料です。

slide17

簡単に言うと、Dockleの列ではイメージの設計が正しくされているか、Trivyの列では脆弱性のあるパッケージが使われていないかをチェックできます。

その他にも、パスワードが設定されていないユーザのチェックなど、Linuxの基礎的なセキュリティもチェックします。
original-checkpoint-comparison.png

ただし、すべてのコンテナで警告が出てしまうので、「latestタグはやめよう」「Content Trustを有効にしよう」の2項目は無視しています。

データの作り方

過去に記事にした Dockle starsTrivy stars を利用しています。
対象のコンテナイメージに対してそれぞれスキャンしていき、結果を集計しました。なお800個のコンテナを平行処理して1時間掛かりませんでした。

なお、私はDockleの作者で、Trivyのメインコミッタの一人です。GitHub Starが増えると喜びます。

フロントエンドやホスト環境は?

reactnetlify.png

メインで使っているライブラリは以下のものです。
Docker Meetup Tokyo #31のLTに間に合わせるべく、画面のベース作成1日というギリギリのスケジュールだったためCreate React Appを利用しました。

├── public : JSONや画像など
├── src : ソースコード
└── yarn.lock

フォルダ構成は現在このようになっており、すべてnetlifyでホストされています。
ただ、ファイルサイズが大きくなるとnetlifyだと極端に遅くなります。
特に脆弱性の数が多いJSONデータのロードで顕著です。解決策があれば教えてください。

脆弱性対策はどうすればいい?

ここや、この記事の後半でお伝えしたとおり、どのように向き合うかは、そのサービスの用途や求めるレベルによります。

ただ、Trivyで検出された脆弱性については、新しいOSにして新しいバージョンのパッケージを入れたら脆弱性は減るので、公開されているDockerfileを元に自らの手で書き直すことをおすすめします。

脆弱性についてより詳しいことが気になった人は、私も参加しているプロジェクト Vulsのチームが主催する 「既知の脆弱性はこう捌け!」系の勉強会に参加すると、体系的に学ぶ事ができます。

最後に

最初に、Docker公式が用意しているイメージが今のところ大丈夫と伝えました。
しかし、いつ脆弱性が入るのかはわからないので、ビルドごとにイメージのチェックすることをおすすめします。実例として、今年の5月まで公式が用意したAlpine LinuxのイメージにRootユーザのパスワードが設定されていないという脆弱性がありました。

ローカルビルドの際に、すでにあるイメージを毎回参照していて、過去の脆弱性をそのまま使い続けている状況もありえます。ローカルでイメージを作成している人/コンテナのイメージをキャッシュから作成されている方は、特に一度スキャンすることをおすすめします。

なお、今後も https://containers.goodwith.tech/ に、ユーザーの入力したイメージ名からスキャンをするなど、機能追加していく予定です。 フッターにシェアボタン付けたので、シェアお願いします?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む