White scenery @showyou, hatena

If you have any comments, you may also send twitter @shsub or @showyou.

JavaScriptから縦持ちのCSVデータを読み取ってPlotly.jsで可視化した

注:方向性が偏っている事をご容赦下さい ちょっとTwitterの発言を集計してcsvファイルにして、それをPlotly.jsを使って、チャートとして表示するプログラムを組みました。

f:id:showyou:20200328134653p:plain

元データ f:id:showyou:20200328134632p:plain

ちょっとチャートの表示時刻と元データで時間がずれてます。

プログラムは、動く実物はこちらにございます。

何をしたか

参考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:サイトへのアクセスありますか? f:id:showyou:20200328134613j:plain

また、集計自体は(Twitter上で公開されてるデータとはいえ)非公式で行ってます。なので公式から怒られたら消します。

集計部分についてのロジックは要望があれば後ほど載せます。

参考

  1. Line Charts in Plotly.js https://plot.ly/javascript/line-charts/
  2. CSVデータをchart.jsでグラフ化する! https://qiita.com/tabetomo/items/f1fa423bf826a1d2efb8