D3.js と reveal.js の紹介

2015/04/29(水)13:00 〜 15:00 開催
ブックマーク

イベント内容

Office のいらない office 環境

この資料は じゃいすと LT 第二回で使用する資料です. LT とか言いつつ,絶対ハンズオンレベルの量になっていて恐縮です. 私の回で話そうと思っていることをすべて書いているので, 事前に確認しておく必要はないです.

   注) このイベントは 北陸先端科学技術大学院大学 (JAIST) の私的内部イベント です.
   そのため,外部の方の参加はご遠慮ください.
   多分交通費がもったいないです.

アジェンダ

  • はじめに
  • reveal.js の簡単な紹介
  • reveal.js ハンズオン
  • D3.js の簡単な紹介
  • D3.jjs ハンズオン

はじめに

プログラミング言語 Office 環境化計画の第一弾です. 私は信仰上の理由から Microsoft が大嫌いです. あの,有料ソフトの癖にどんなパソコンにも入っていて, みんな使って当たり前感がなんとも.

なので,その呪縛からの脱却を目指します. その手始めとして,Power Point をやっつけます. つまり,ここで紹介するハックは基本的に発表資料を作成する際に, Power Point を使用しないでどのように行って行くのかという話しをして, その結果 better than "power point" な部分,みんなが happy になる部分を紹介します.

js とは何か?

java script というプログラム言語を聞いたことのないプログラム畑の人は現在では 相当減っていると思います. 比較的簡単にスクリプトが書け,割と応用範囲が広いので最近特に人気の(そしてその分忌み嫌われる)言語の 一つかと思います.

一般には web ページ,あるいは web app を作成する時に使用する言語で,web 系の何かを作成するとき以外には 使い道が... などと思いがちですが(というか私はそう思っていたのですが),基本的にあれは DOM (HTML のようにツリー構造でマークした文章) を動的に操作するツールであることを思えば,別に web で公開せずにローカルで使用していてもいいんですよね.

だって DOM って要は装飾のついた文章ファイルで,GUI の実装方法の一つなわけです.

Office とは何か?

大抵のローカルアプリだって GUI は xml で指定していますし,いわゆるベクター形式のファイルだって DOM の一種です.もっと言ってしまうと例えば Libre office を zip に変換すると結局は web ページのような構造に 過ぎないことに気がつくと思います.

つまり,いわゆる office 系のアプリケーションの最終的な出力ファイルって,web ページ用のディレクトリを圧縮した圧縮ファイルそのものにすぎず, office アプリとはその圧縮ファイルのビュワーとエディタがセットになった統合開発環境に過ぎないわけです.

そこで, js を office 環境として使用するという行為を考えるとつまり以下のような要素に分解できるわけです.

  • ファイル: 圧縮ファイル -> 作業ディレクトリ
  • ビュワー: power point -> firefox (chrome)
  • コンパイラ??: power point -> js
  • エディタ: power point -> vim (emacs その他)

こう考えてみるとスクリプティングをすることで office 環境の機能を再現するという試みが, そんなにとんでも無い発想ではないということがお分かりいただけるかと思います.

reveal.js の紹介

power point でできること

今回はアンチパワポなので,まず power point でできる機能を整理してみましょう.

  • スライドという枠の作成
  • スライドの移動
  • 文字の表示
  • 表の表示
  • ファイルの埋め込み

大体上記のことができれば power point の機能は再現していると言えるのではないでしょうか? 実はこれらの機能に関してはすでに js で実装済みのライブラリが存在します.

reveal.js とは

さて,では早速 js + html でスライド作成をしていきましょう. とは言いつつ,ここでは何か js をいじることはしません. 単純にそれ用の js を利用します.

ここでは個人的な使用感の違和感のなさから reveal.js を紹介します.

公式サイト自身が leveal.js のデモになっているので面白いと思います.

ちなみに, html + js でスライドを作成するという発想は結構普通で,以下のようなライブラリもあります.

reveal.js ハンズオン

まずは github からソースをダウンロードします. 実は web app 化もしているのですが,なんだかんだでローカルのものを使用したほうが楽かと思います.

基本

ソースファイルをダウンロードしたら,早速 index.html を適当なブラウザ(適当と言った段階で IE は外します)で開いてみてください.

大体サンプルファイルがどのようになっているのかが把握できると思います. js の読み込みとか head 要素に関しては,ここでは省略します. とりあえずは, ソースファイルにある index.html を加工する形で使用してください.

肝心なのは body 要素の記述です. スライド本体は以下のような div 要素で区切られます.

<div class="reveal">
    <div class="slides">
        スライド本体
    <div>
</div>

また各スライドは以下の div で区切られます.

<div class="slides">
    何か文章
<div>

この場合,スライドは横に動くようになります. 一方スライドクラスの div を二重にすると縦に移動します.

<div class="slides">
    <div class="slides">
        何か文章
    <div>
<div>

"何か文章" と書かれている部分には一般的な html の要素を直接書き込めばよいです.

これで,スライドの作成,スライドの移動,文字の表示, ファイルの埋め込み(リンク) という機能が使用できることを確かめました.

アニメーション

power point の機能ではある文字をアニメーションを使って表示したり消したりできます. reveal.js も同様の機能が埋め込まれています.

<section>
    <h2>Fragment Styles</h2>
    <p>There's different types of fragments, like:</p>
    <p class="fragment grow">grow</p>
    <p class="fragment shrink">shrink</p>
    <p class="fragment roll-in">roll-in</p>
    <p class="fragment fade-out">fade-out</p>
    <p class="fragment current-visible">current-visible</p>
    <p class="fragment highlight-red">highlight-red</p>
    <p class="fragment highlight-blue">highlight-blue</p>
</section>

とすると使えるアニメーションの書き方がわかるかと思います.

シンタックスハイライト

特にプログラミング系のスライドを書くと, スライド中にシンタックスハイライトでコードを表示したい場合があります. 以下のようにするとそれができます.

<pre>
    <code class="javascript" data-trim contenteditable style="font-size: 18px;">
    Reveal.addEventListener( 'customevent', function() {
        console.log( '"customevent" has fired' );  
    } );
    </code>
</pre>

ここはへんは power point には無い機能です.

マークダウンで書いてみる

html は 表現力の大変優れた記法ですが, めんどいです.

reveal.js では MarkDown でスライドを書くこともできます.

<section data-markdown>
    <script type="text/template">
    ## Markdown support

    Write content using inline or external Markdown.
    Instructions and more info available in the
    [readme](https://github.com/hakimel/reveal.js#markdown).
    </script>
</section>
  • md 形式の場合, class を宣言できなくなります.
  • これは section 単位で指定できるので,凝ったことをしたいスライドでは html 形式で, 単純なスライドでは md 形式でスライドを作成するとよいです

github にポストする

作成したスライドは github 上で直接公開することも可能です. 公開するには, gh-pagesブランチに作成したファイルをpush します. github では gh-pages ブランチにある index.html ファイルを公開してくれます. これは以下のページがわかりやすいです.

D3.js

ここまでで, reveal.js を使えば,大体 power point でできることは再現できるし, 論理上,すべての web app で実装されていることはすべてスライドの表現方法として実行可能であることが お分かりになるかと思います.

ただし,上記のやり方では,一点問題があります. それが図です.

reveal.js のみで図を使用する場合,基本的には表示したい図のpngファイルを用意することになると思います. この図をどうやって作成するのかという問題が出てきます(個人的にはRのggplotライブラリが便利なのですが,これはまた別の機会にでも).

せっかくなら図に関しても js で完結したいと思う場合もあるでしょう.

js を使用して図を作成する方法を紹介する前に,少し,PC 上の図に関して基本的な事項を 確認しておきます.まず, PC 上で図を表現するには 2 通りの形式があります.

  • ビットマップ (ex. jpg, png)
  • ベクター (ex, ai, svg, ps, pdf, css)

前者の実装方法では描画領域すべての座標に対し,一つ一つのパラメータが指定されています. 座標点に対するサンプリングと理解することも出来ますので,ある意味,完全指定で図を作成する方法です.

一方後者は,数式で図を表現する方法です. つまり,ある線の開始,終了を定義し,その線のパラメータを定義します. そのため,後者のやり方では,絶対的な座標軸は存在する必要がなく,拡大,縮小が自由です. また,事後的に座標軸を定義してやることによって,アニメーションを作成することも可能です.

ベクター形式は,上記の通りの方法論なので,一般に DOM で実装されていることが多いです. そのため 当然 js で作成することが可能です.

D3.js とは?

js を使用して図を作成する方法として今熱いのは D3.js だと思います(最近ではこれをエクセルのプラグインとして使用できたりもします.). ちなみに D3 の意味は Data-Driven Documents ですね.

とりあえず公式サイトから面白いデモを引っ張って来たので見てみてください.

楽しいでしょ? D3.js は reveal.js との相性がよく(競合が起きない), 動的な図を作成することができます.

一般的には JSON でデータを受け取ることが多いのですが, CSV ファイルを読み込むことも可能です. ベクター形式にし,HTML と組み合わせることで,発表中に動的に操作可能な作図が可能で,

しかも,データは抽象化できるので,急なデータ変更があってもいちいちスライドを修正する必要がありません(このへん,プロトタイプ言語は強いです).ある API を叩いて作図を行う場合,発表中のまさに今起きている現象を提示することも可能です.

D3.js ハンズオン

では実際に使用してみましょう. 今回は時間の都合で,そんなに入り組んだことはせず,単純な例のハンズオンをお見せします.

とりあえず,基本的な使い方として iris のデータを読み込んで散布図をやヒストグラムを書いて見ましょう. それが済んだら,次はこれを動的に動かせるようにしてみます.

D3.js を読み込む

D3.js を読み込みます. D3.js のソースコードをダウンロードしてもいいのですが,html 内部に直接パスを書いてしまったほうが楽かと思います.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3.js サンプル</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>

<body>
<h1>D3.jsサンプル</h1>

<script>
ここに D3 用のコードを記述
</script>

</body>
</html>

D3 で散布図を書いてみる

まずは単純にデータを直書きした上でそのデータを散布図にします. 以下,サンプルデータです.

/* データの宣言 */
var dataset = [
  [   5,   150 ],
  [ 480,   300 ],
  [ 250,   400 ],
  [ 100,   330 ],
  [ 330,   50 ],
  [ 410,   120 ],
  [ 475,   340 ],
  [  25,   470 ],
  [  85,   210 ],
  [ 220,   380 ]];

/* 描画領域の指定 */
var svg = d3.select("body")
    .append("svg")
    .attr("width", 1000)
    .attr("height", 1000);

/* データの描画 */
svg.selectAll("circle")  // 円を選択
  .data(dataset)         // データを当てはめる
  .enter()               
  .append("circle")      // 実際に円をhtmlに追加
  .attr({                // 円の細かい設定は以下の通り
    cx : function(d) {return d[0]},
    cy : function(d) {return d[1]},
    r : 10,
  })

var dataset の部分は単純にデータを作成しているだけです.

var svg では描画する範囲を指定しています. body要素内部に縦横 1000px の svg を作成しています.

で,この svg に円(circle) を作成します.ここの点は dataset を利用します. attr() の部分で座標と半径の大きさを指定しています.

ここで先に円(circle)要素をセレクトしていることに注意してください. 実際に要素が存在しない状態でも先にデータの宣言をし,あとでその要素をhtmlに追加できます.

data(dataset) に関しては説明が必要かもしれません.これは引数に与えられた数だけ,それ以降の処理を 繰り返し実行します.今回は 10 個のリストが入っているリストを渡しているので, 10 回繰り返し,以下の処理を 行います.この際,まさに処理しているデータ自身は変数 d に格納されます.

この例で D3.js の基本的な流れがつかめるかと思います. まず,データを宣言し(今回はベタ書きしましたが,csv, json などが読み込めます), 描画領域を作成します. で,その描画領域にのせるものを追加して,データを当てはめるわけです.

データの読み込み

D3.js を使用すれば,いろいろできるのはわかったとして,実際に使用することを考えると, データの読み込みが必要です.

ここでは一番一般に流布しているデータ形式である csv ファイルを読み込んでみます.

/* データの宣言 */
d3.csv('iris.csv', function(dataset) {
    /* 描画領域の指定 */
    var svg = d3.select("body")
        .append("svg")
        .attr("width", 900)
        .attr("height", 500);

    /* データの描画 */
    console.log(dataset)
    svg.selectAll("circle")  // 円を選択
      .data(dataset)         // データを当てはめる
      .enter()
      .append("circle")      // 実際に円をhtmlに追加
      .attr({                // 円の細かい設定は以下の通り
        cx : function(d){return d["SepalLength"] * 100},
        cy : function(d){return d["SepalWidth"] * 100},
        r : 3,
      });
});
  • csv はこの勉強会用のgithub レポジトリ内に含まれています.
    • 以下の記述はヘッダのついている csv ファイルようです

D3 で軸を表示する

学術的な作図の場合,スケールの表示はとても重要な問題です.

D3 でアニメーションを作成してみる

基本的に,D3 で各要素を作成している部分にいろいろと細工をしていけば, 自由にアニメーションが作成できます.

実際に先ほどの例を利用して最も単純なアニメーションをつけてみます. サンプルは以下の通りです.

svg.selectAll("circle")
   .data(dataset)
   .enter()
   .append("circle")
   .transition()
   .delay(500)
   .attr({
      cx : function(d) {return d[0]},
      cy : function(d) {return d[1]},
      r : 10,
    })

違いは transition と delay の部分のみです. transition はこの要素を変化させるという意味です. それに対して,どう動かすのかを決めているのが後続の行です. まず,delay() は単純な待機です.500 msec 待機します. その後,各要素の値を指定しているので,表示されてから 500msec は何も表示されず,その後 各点が表示されます.

もちろん先に circle の変数を決めてしまい後から変更することもできます.

svg.selectAll("circle")
   .data(dataset)
   .enter()
   .append("circle")
   .attr({
      cx : function(d) {return d[0]},
      cy : function(d) {return d[1]},
      r : 10,
    })

svg.transition().delay(500).duration(1000)
   .attre("fill", "red")

この例の場合,500msec 後に 1sec かけて各点の色を赤くします.

クリックとの連携

上記の例では読み込まれたあと自動で処理を開始しました. しかし,実際の使用シーンではユーザーの挙動に応じて図を変更したい場合が多々あるかと思います. ここでは簡単にクリックを取得する方法のみを紹介します.

svg.selectAll("circle")  // 円を選択
  .data(dataset)         // データを当てはめる
  .enter()
  .append("circle")      // 実際に円をhtmlに追加
  .attr({                // 円の細かい設定は以下の通り
    cx : function(d) {return d[0]},
    cy : function(d) {return d[1]},
    r : 10,
  })
  .on("click",function(){
      svg.transition()
          .duration(1000)
          .attr("fill", "red")
  })

ポイントは on の部分です.ここでクリックを取得した際に以下の処理を行うと宣言できます.

reveal.js と D3.js を連携してみる

注意事項

※ こちらのイベント情報は、外部サイトから取得した情報を掲載しています。
※ 掲載タイミングや更新頻度によっては、情報提供元ページの内容と差異が発生しますので予めご了承ください。
※ 最新情報の確認や参加申込手続き、イベントに関するお問い合わせ等は情報提供元ページにてお願いします。