Last active
September 15, 2016 08:35
-
-
Save mnishiguchi/287d4043c7b69442af23 to your computer and use it in GitHub Desktop.
React.js + Chart.jsでインタラクティブなグラフを書く ref: http://qiita.com/mnishiguchi/items/226c0a4bd85e4da54f42
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
R = React.DOM | |
# Canvases for charts | |
PieChartCanvas = React.createClass | |
render: -> | |
R.canvas | |
style: { height: 200, width: 200 } | |
BarChartCanvas = React.createClass | |
render: -> | |
R.canvas | |
style: { height: 200, width: 400 } | |
@MovingRecordsApp = React.createClass | |
getInitialState: -> | |
records: @props.data | |
# Remember Chart.js instances so we can delete them later. | |
barChartInstance: null | |
pieChartInstance: null | |
getDefaultProps: -> | |
records: [] | |
addRecord: (record) -> | |
records = React.addons.update(@state.records, { $unshift: [record] }) | |
@setState records: records | |
deleteRecord: (record) -> | |
index = @state.records.indexOf record | |
records = React.addons.update(@state.records, { $splice: [[index, 1]] }) | |
@replaceState records: records | |
updateRecord: (record, newRecord) -> | |
index = @state.records.indexOf record | |
records = React.addons.update(@state.records, { $splice: [[index, 1, newRecord]] }) | |
@replaceState records: records | |
chartsPanel: -> | |
R.div | |
className: "panel panel-blue" | |
R.div | |
className: 'panel-heading' | |
R.div | |
className: "row" | |
R.div | |
className: "col-xs-3" | |
R.div | |
className: "fa fa-home fa-5x" | |
R.div | |
className: "col-xs-9 text-right" | |
R.div | |
className: 'huge' | |
"Total: #{@totalVolume()}" | |
R.div null, | |
"cubic feet" | |
R.div | |
className: 'panel-body' | |
R.div | |
className: 'row text-center' | |
R.div | |
className: 'col-sm-6' | |
React.createElement BarChartCanvas, | |
ref: "bar" | |
R.div | |
className: 'col-sm-6' | |
React.createElement PieChartCanvas, | |
ref: "chart" | |
totalVolume: -> | |
sum = 0 | |
for obj in @state.records | |
sum += (obj.volume * obj.quantity) | |
sum | |
render: -> | |
R.div | |
className: "app_wrapper" | |
@chartsPanel() | |
R.hr null | |
R.h2 null, "Add a new item" | |
React.createElement NewMovingRecordForm, | |
handleNewRecord: @addRecord | |
roomSuggestions: @props.roomSuggestions | |
categorySuggestions: @props.categorySuggestions | |
R.hr null | |
React.createElement Records, | |
records: @state.records, | |
handleDeleteRecord: @deleteRecord, | |
handleUpdateRecord: @updateRecord | |
# 部品がDOMに搭載された後に、グラフを書く。 | |
componentDidMount: -> | |
@drawCharts() | |
# 部品が更新された後に、古いグラフを破壊し新しいグラフを書く。 | |
componentWillUnmount: -> | |
@state.barChartInstance.destroy() | |
@state.pieChartInstance.destroy() | |
# DOM上のキャンバスを探し、そこにグラフを描画。 | |
drawCharts: -> | |
# 棒グラフ | |
canvas = React.findDOMNode(@refs.bar) # refを手掛かりにキャンバスを探します。 | |
ctx = canvas.getContext("2d") # 絵を書くための場所をゲットします。 | |
# グラフ用データを渡し、グラフのオブジェクトを作ります。 | |
# そのオブジェクトを後ほど破壊するためにポインターを保存しておきます。 | |
@setState.barChartInstance = new Chart(ctx).Bar(@dataForBarChart()) | |
# 円グラフ | |
canvas = React.findDOMNode(@refs.chart) | |
ctx = canvas.getContext("2d") | |
@setState.pieChartInstance = new Chart(ctx).Pie(@dataForPieChart()) | |
dataForPieChart: -> | |
[ | |
{ | |
value: 300 | |
color:"#F7464A" | |
highlight: "#FF5A5E" | |
label: "Red" | |
} | |
{ | |
value: 50 | |
color: "#46BFBD" | |
highlight: "#5AD3D1" | |
label: "Green" | |
} | |
{ | |
value: 100 | |
color: "#FDB45C" | |
highlight: "#FFC870" | |
label: "Yellow" | |
} | |
] | |
dataForBarChart: -> | |
labels: ["January", "February", "March", "April", "May", "June", "July"] | |
datasets: [ | |
{ | |
label: "My First dataset" | |
fillColor: "rgba(220,220,220,0.5)" | |
strokeColor: "rgba(220,220,220,0.8)" | |
highlightFill: "rgba(220,220,220,0.75)" | |
highlightStroke: "rgba(220,220,220,1)" | |
data: [65, 59, 80, 81, 56, 55, 40] | |
} | |
{ | |
label: "My Second dataset" | |
fillColor: "rgba(151,187,205,0.5)" | |
strokeColor: "rgba(151,187,205,0.8)" | |
highlightFill: "rgba(151,187,205,0.75)" | |
highlightStroke: "rgba(151,187,205,1)" | |
data: [28, 48, 40, 19, 86, 27, 90] | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dataForPieChart: -> | |
source = @volumeSortedBy("room") | |
ary = [] | |
colors = ["#FE2E2E", "#FE9A2E", "#F7FE2EB", "#9AFE2E", "#2EFE2E", "#2EFE9A", | |
"#2EFEF7", "#2E9AFE", "#2E2EFE", "#9A2EFE", "#FE2EF7", "#FE2E9A"] | |
@shuffleArray(colors) | |
for item, i in source | |
obj = | |
value: item.volume | |
color: colors[i] | |
highlight: colors[i] | |
label: item.room | |
ary.push(obj) | |
ary | |
dataForBarChart: -> | |
source = @volumeSortedBy("category") | |
labels = source.map (obj) -> obj.category | |
data = source.map (obj) -> obj.volume | |
datasets = [ | |
{ | |
fillColor: "rgba(151,187,205,0.5)" | |
strokeColor: "rgba(151,187,205,0.8)" | |
highlightFill: "rgba(151,187,205,0.75)" | |
highlightStroke: "rgba(151,187,205,1)" | |
data: data | |
} | |
] | |
{ labels: labels, datasets: datasets } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
# 部品がDOMに搭載された後に、グラフを書く。 | |
componentDidMount: -> | |
@drawCharts() | |
# 部品が更新された後に、古いグラフを破壊し新しいグラフを書く。 | |
componentWillUnmount: -> | |
@state.barChartInstance.destroy() | |
@state.pieChartInstance.destroy() | |
# DOM上のキャンバスを探し、そこにグラフを描画。 | |
drawCharts: -> | |
# 棒グラフ | |
canvas = React.findDOMNode(@refs.bar) # refを手掛かりにキャンバスを探します。 | |
ctx = canvas.getContext("2d") # 絵を書くための場所をゲットします。 | |
# グラフ用データを渡し、グラフのオブジェクトを作ります。 | |
# そのオブジェクトを後ほど破壊するためにポインターを保存しておきます。 | |
@setState.barChartInstance = new Chart(ctx).Bar(@dataForBarChart()) | |
# 円グラフ | |
canvas = React.findDOMNode(@refs.chart) | |
ctx = canvas.getContext("2d") | |
@setState.pieChartInstance = new Chart(ctx).Pie(@dataForPieChart()) | |
# 棒グラフ用データ(これはドキュメンテーションから引用した例) | |
# ここで実際は@state.recordsのデータを加工してデータを準備します。 | |
dataForBarChart: -> | |
labels: ["January", "February", "March", "April", "May", "June", "July"] | |
datasets: [ | |
{ | |
label: "My First dataset" | |
fillColor: "rgba(220,220,220,0.5)" | |
strokeColor: "rgba(220,220,220,0.8)" | |
highlightFill: "rgba(220,220,220,0.75)" | |
highlightStroke: "rgba(220,220,220,1)" | |
data: [65, 59, 80, 81, 56, 55, 40] | |
} | |
{ | |
label: "My Second dataset" | |
fillColor: "rgba(151,187,205,0.5)" | |
strokeColor: "rgba(151,187,205,0.8)" | |
highlightFill: "rgba(151,187,205,0.75)" | |
highlightStroke: "rgba(151,187,205,1)" | |
data: [28, 48, 40, 19, 86, 27, 90] | |
} | |
] | |
# 円グラフ用データ(これはドキュメンテーションから引用した例) | |
# ここで実際は@state.recordsのデータを加工してデータを準備します。 | |
dataForPieChart: -> | |
[ | |
{ | |
value: 300 | |
color:"#F7464A" | |
highlight: "#FF5A5E" | |
label: "Red" | |
} | |
{ | |
value: 50 | |
color: "#46BFBD" | |
highlight: "#5AD3D1" | |
label: "Green" | |
} | |
{ | |
value: 100 | |
color: "#FDB45C" | |
highlight: "#FFC870" | |
label: "Yellow" | |
} | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@MovingRecordsApp = React.createClass | |
getInitialState: -> | |
records: @props.data | |
# グラフのオブジェクトを覚えておくための変数。 | |
barChartInstance: null | |
pieChartInstance: null |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# React.DOMの記述を省略するための変数。 | |
R = React.DOM | |
PieChartCanvas = React.createClass | |
render: -> | |
R.canvas | |
style: { height: 200, width: 200 } | |
BarChartCanvas = React.createClass | |
render: -> | |
R.canvas | |
style: { height: 200, width: 400 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# React.DOMの記述を省略するための変数。 | |
R = React.DOM | |
# メインの部品 | |
@MovingRecordsApp = React.createClass | |
getInitialState: -> | |
records: @props.data # 外部から供給されるデータ。 | |
# グラフのオブジェクトを覚えておくための変数。 | |
barChartInstance: null | |
pieChartInstance: null | |
getDefaultProps: -> | |
records: [] | |
... | |
# グラフと額縁のテンプレート | |
chartsPanel: -> | |
R.div | |
className: "panel panel-blue" | |
R.div | |
className: 'panel-heading' | |
R.div | |
className: "row" | |
R.div | |
className: "col-xs-3" | |
R.div | |
className: "fa fa-home fa-5x" | |
R.div | |
className: "col-xs-9 text-right" | |
R.div | |
className: 'huge' | |
"Total: #{@totalVolume()}" | |
R.div null, | |
"cubic feet" | |
R.div | |
className: 'panel-body' | |
R.div | |
className: 'row text-center' | |
# 棒グラフ用キャンバス | |
R.div | |
className: 'col-sm-6' | |
React.createElement BarChartCanvas, | |
ref: "bar" # 後にアクセスするために使用 | |
# 円グラフ用キャンバス | |
R.div | |
className: 'col-sm-6' | |
React.createElement PieChartCanvas, | |
ref: "chart" # 後にアクセスするために使用 | |
render: -> | |
R.div | |
className: "app_wrapper" | |
# グラフと額縁 | |
R.div null, @chartsPanel() | |
R.hr null | |
# 新規作成フォームの部品(この部品についての本題ではないので、詳細は省略しています。) | |
R.h2 null, "Add a new item" | |
React.createElement NewMovingRecordForm, | |
handleNewRecord: @addRecord | |
roomSuggestions: @props.roomSuggestions | |
categorySuggestions: @props.categorySuggestions | |
R.hr null | |
# 表の部品(この部品についての本題ではないので、詳細は省略しています。) | |
React.createElement Records, | |
records: @state.records, | |
handleDeleteRecord: @deleteRecord, | |
handleUpdateRecord: @updateRecord | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dataForPieChart: -> | |
source = @volumeSortedBy("room") | |
ary = [] | |
colors = ["#FE2E2E", "#FE9A2E", "#FE9A2E", "#9AFE2E", "#2EFE2E", "#2EFE9A", | |
"#2EFEF7", "#2E9AFE", "#2E2EFE", "#9A2EFE", "#FE2EF7", "#FE2E9A"] | |
@shuffleArray(colors) | |
for item, i in source | |
obj = | |
value: item.volume | |
color: colors[i] | |
highlight: colors[i] | |
label: item.room | |
ary.push(obj) | |
ary | |
dataForBarChart: -> | |
source = @volumeSortedBy("category") | |
labels = source.map (obj) -> obj.category | |
data = source.map (obj) -> obj.volume | |
datasets = [ | |
{ | |
fillColor: "rgba(151,187,205,0.5)" | |
strokeColor: "rgba(151,187,205,0.8)" | |
highlightFill: "rgba(151,187,205,0.75)" | |
highlightStroke: "rgba(151,187,205,1)" | |
data: data | |
} | |
] | |
{ labels: labels, datasets: datasets } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment