JavaScriptから縦持ちのCSVデータを読み取ってPlotly.jsで可視化した
注:方向性が偏っている事をご容赦下さい ちょっとTwitterの発言を集計してcsvファイルにして、それをPlotly.jsを使って、チャートとして表示するプログラムを組みました。
元データ
ちょっとチャートの表示時刻と元データで時間がずれてます。
プログラムは、動く実物はこちらにございます。
- プログラム:https://github.com/showyou/vote_shadow_scfes/blob/master/plot.js
- 実物:https://vote-shadow-scfes.netlify.com/chart.html
何をしたか
参考1に沿ってLine+markersのチャートを作るのと、参考2を参考にcsvからチャートに行う物の、両方を行いました。
まずcsv2Arrayでcsvデータを配列にしています。これは参考2と一緒です。
function csv2Array(str) { var csvData = []; var lines = str.split("\n"); for (var i = 0; i < lines.length; ++i) { var cells = lines[i].split(","); csvData.push(cells); } return csvData; }
次に名前が与えられた時に、それが何番目かを返す関数を作っています。これは、恐らくplotするときのデータに連想配列が使えないからです。
今さらだけどforループしなくてもhoge['名前'] = 要素番号
にしておけばもっと効率いいことに気づきました。でももっとマシな方法はあるはずです。
// n をidに変換する function getId(name, n){ for ( i = 0; i < 9; i++){ //console.log(i) //console.log(name[i]); //console.log(n); if( name[i] == n ){ return i } } return -1 }
最後にチャートを描画する部分です。これも参考2をベースにしてますが、
- データが縦持ちである
- Plotlyを使っている
辺りでアレンジをしています。
今回種別が9種類と決まっているので、forループで9回と固定してます。通常は連想配列の大きさを見たほうがいいかもしれません。 names, colorsはほぼ定数なので関数の外に出してます。
あとちなみに普段はPython使ってるのでJavaScriptは詳しくありません。Pythonならdefaultdictとか使えるんだけどなぁ。
function drawLineChart(data, div) { var output = {}; // データを入れるところ var x = [], y = []; var i; //配列の配列の、初期化 for ( i = 0; i < 9; i++){ x[i] = []; y[i] = []; } // データ1行毎に、xyに値を格納 for (var row in data){ id = getId(names, data[row][1]); //console.log(id) if(id >= 0){ x[id].push(data[row][0]); y[id].push(data[row][2]); } } var output = []; for ( i = 0; i < 9; i++){ output[i] = { name: names[i], x: x[i], y: y[i], line: { color: color[i] }, mode: 'lines+markers' } } var layout = {}; Plotly.newPlot(div, output, layout, {showSendToCloud: true}); }
補足
Q:サイトへのアクセスありますか?
また、集計自体は(Twitter上で公開されてるデータとはいえ)非公式で行ってます。なので公式から怒られたら消します。
集計部分についてのロジックは要望があれば後ほど載せます。
参考
- Line Charts in Plotly.js https://plot.ly/javascript/line-charts/
- CSVデータをchart.jsでグラフ化する! https://qiita.com/tabetomo/items/f1fa423bf826a1d2efb8