- 投稿日:2019-10-02T21:29:13+09:00
react-chartjs-2とChart.jsを使ってグラフを作ってみた
最近Reactを勉強しており、その際にグラフを作りたいと思いました。react-chartjs-2の提供もされていたので、今回は「Chart.js」を使用することにしました。
今回は線グラフですが、他にも円グラフや棒グラフなど色々あります。
https://jerairrest.github.io/react-chartjs-2/
また詳しい導入法は公式ドキュメントから確認できます。
https://github.com/jerairrest/react-chartjs-2完成時のイメージとコードは下です。
必要となる「react-chartjs-2」と「chart.js」のインストールyarn add react-chartjs-2 chart.jsApp.jsimport React from "react"; import LineExample from './Line'; function App() { return ( <div className='App'> <LineExample /> </div> ); } export default App;Line.jsimport React from 'react'; import {Line} from 'react-chartjs-2'; const data = { labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], datasets: [ { label: 'My First dataset', fill: true, lineTension: 0.1, backgroundColor: 'rgba(75,192,192,0.4)', borderColor: 'rgba(75,192,192,1)', borderCapStyle: 'round', borderDash: [], borderDashOffset: 0.0, borderJoinStyle: 'square', pointBorderColor: 'rgba(75,192,192,1)', pointBackgroundColor: '#eee', pointBorderWidth: 10, pointHoverRadius: 5, pointHoverBackgroundColor: 'rgba(75,192,192,1)', pointHoverBorderColor: 'rgba(220,220,220,1)', pointHoverBorderWidth: 1, pointRadius: 1, pointHitRadius: 10, data: [3, 10, 21, 31, 34, 40, 48] } ] }; const LineExample = () => { return ( <div> <h2>Line Example</h2> <Line data={data} /> </div> ); } export default LineExample;上の例では一つの線グラフでしたが、複数のグラフを表示することもデザインを加えることもできます。
複数のグラフを表示する方法がわからなかった時に参考になったstackoverflowも一緒にのせておきます。
create a multi line chart using Chart.js
参考文献
react-chartjs-2
react-chartjs-2のgithub
create a multi line chart using Chart.js
- 投稿日:2019-10-02T14:42:20+09:00
gatsby: command not found とエラーが出た時の対応
一般的なgatsbyのことはじめ
公式の手順通りにインストールしてくる
https://www.gatsbyjs.org/docs/quick-start
npm install -g gatsby-cli
gatsby: command not found と上手くいかない時がある
上記のコマンドではPCの設定などによっては上手くインストールできない場合があるようです。
そのためyarnを使用してインストールし直すと上手くいく。yarnのインストールはこちらから
https://yarnpkg.com/lang/en/docs/install/#mac-stable
sudo yarn global add gatsby-cli
上記のコマンドでやり直したところ上手くいきました。
- 投稿日:2019-10-02T11:48:47+09:00
React-Reduxが難しい? それは過去の話だ! ~ ToDoアプリを最小限の労力で記述する ~
Reduxが難しい? それは過去の話だ! ~ ToDoアプリを最小限の労力で記述する ~
React-Reduxを簡単に利用するためのパッケージ@jswf/redux-moduleを利用して、最小限の労力でToDoアプリを作成するという内容です。
※追記
@jswf/redux-moduleの使い方は以下記事で、もう少し短いソースにて確認できます
React-ReduxだけどReducerもActionも書かず、Dispatchすら使わず、データも何となく受け取れるようにする方法最初に
プログラムはファイル一つだけにまとめました。
内容は以下のように構成されています。
- データ構造の定義
- データ操作用クラスの作成
- データ入力用コンポーネント
- データ表示用コンポーネント
今回はReduxラッパーの機能を使うため、データの入力と表示はコンポーネントは分けてあります。
ここで見ていただきたいのは、propsもuseStateも使っていないということです。
全てのデータはReduxのStore上に格納されます。
しかしReduxを使う上での前提となるFlux的な定義は一切書く必要がありません。
ReduxModuleクラスを継承することによって、読み書き全ての手続きがReduxModuleで定義されているsetStateとgetStateメソッドに集約されます。作ったもの
ソースコード
index.tsximport React from "react"; import * as ReactDOM from "react-dom"; import { createStore } from "redux"; import { Provider } from "react-redux"; import { ModuleReducer, useModule, ReduxModule } from "@jswf/redux-module"; /** *データ構造の定義(TypeScript使用時) * * @export * @interface TodoState */ interface TodoState { //入力中データの保持 input: { title: string; desc: string; }; //TODOリスト todos: { id: number; title: string; desc: string; done: boolean; }[]; //TODOのID附番表index index: number; } /** *Todoデータ管理用クラス * * @export * @class TodoModule * @extends {ReduxModule<TestState>} */ export class TodoModule extends ReduxModule<TodoState> { //初期値 protected static defaultState: TodoState = { todos: [], input: { title: "", desc: "" }, index: 0 }; /** *ToDoリストを返す * * @returns * @memberof TodoModule */ public getTodos() { return this.getState("todos")!; } /** *ToDoを追加(追加データはStoreに入っているので引数不要) * * @memberof TodoModule */ public addTodo() { //indexのインクリメント const index = this.getState("index")! + 1; this.setState({ index }); //必要データの読み出し const title = this.getState("input", "title")!; const desc = this.getState("input", "desc")!; //todoを追加 const todos = [ ...this.getState("todos")!, { id: index, title, desc, done: false } ]; this.setState({ todos })!; } /** *ToDoの状態管理 * * @param {number} id * @param {boolean} done * @memberof TodoModule */ public updateDone(id: number, done: boolean) { const srcTodos = this.getState("todos")!; //状態の書き換え const todos = srcTodos.map(todo => todo.id === id ? { ...todo, done } : todo ); this.setState({ todos }); } /** *ToDoの削除 * * @param {number} id * @memberof TodoModule */ public remove(id: number) { const srcTodos = this.getState("todos")!; //削除データを除外 const todos = srcTodos.filter(todo => todo.id !== id); this.setState({ todos }); } } /** *入力フォームコンポーネント * * @returns */ function FormComponent() { const todoModule = useModule(TodoModule); return ( <div style={{ textAlign: "center" }}> <div> <div>タイトル</div> <input style={{ width: "20em" }} value={todoModule.getState("input", "title")!} onChange={e => todoModule.setState(e.target.value, "input", "title")} /> <div>説明</div> <textarea style={{ width: "20em", height: "5em" }} value={todoModule.getState("input", "desc")!} onChange={e => todoModule.setState(e.target.value, "input", "desc")} /> <div> <button onClick={() => todoModule.addTodo()}>Todoを作成</button> </div> </div> </div> ); } /** *ToDo出力コンポーネント * * @returns */ function TodoListComponent() { const todoModule = useModule(TodoModule); const todos = todoModule.getState("todos")!; return ( <div style={{ display:"flex",flexDirection: "column" ,alignItems:"center"}}> {todos.map(todo => ( <div key={todo.id} style={{ display: "inline-block", width: "20em", marginTop: "1em", border: "solid 1px", textAlign:"center" }} > <div> {todo.id}:{todo.title}{" "} <span style={{ cursor: "pointer" }} onClick={() => todoModule.updateDone(todo.id, !todo.done)} > {todo.done ? "完了" : "未完了"} </span> {todo.done && ( <span style={{ cursor: "pointer" }} onClick={() => todoModule.remove(todo.id)} > 削除 </span> )} </div> <div>{todo.desc}</div> </div> ))} </div> ); } //Reduxに専用のReducerを関連付ける //他のReducerと併用することも可能 const store = createStore(ModuleReducer); ReactDOM.render( <Provider store={store}> <FormComponent /> <TodoListComponent /> </Provider>, document.getElementById("root") as HTMLElement );まとめ
ほぼReduxの影や形が消え去っています。
今回の内容はコンポーネント間の連係や、データをStoreに集約することが目的であれば、かなり便利に使えると思います。パフォーマンスを考えて作る場合は、副作用の影響範囲を最小限に抑えるためデータ操作用のクラスを細分化したり、書き込みのみしか利用しないコンポーネント上ではwriteOnly属性を付けたりとチューニングが必要になりますが、それは別の記事で解説を入れたいと思います。
Reduxの定義に疲れ果てた方はぜひ使ってみてください。
リンク