ドーナツチャートで見出しを可視化してmarkdownをもっと便利に使う

Data Visualization Advent Calendarの25日目の記事です。

HTMLの文章構造をドーナツチャートで視覚化して、インデントの深さと進捗率を直感的に把握するツールを作ってみました。こんな感じです。

![Screenshot_2015-12-26-00-55-05.png](https://qiita-image-store.s3.amazonaws.com/0/36728/adcab650-e14e-b190-4f42-f7c4538c1f1c.png)

調べてみても、意外とありそうでなかったので今回作ってみました。このアプローチは人類史上初ではないかと思われます笑。
[ちなみに、デモページも作ってみました。](https://kenji0x02.github.io/donut-indent/sample.html)
以下の説明とほぼ同じ内容ですので、ここからは是非、デモページでお読みください！！

成果物はGithubで公開していますので、もしよければご覧ください。
https://github.com/kenji0x02/donut-indent

## 導入

### 背景

私たちが日々読んでいる文章の多くは、その内容のまとまりをわかりやすく表現するため、章、節、項、目といった見出しをつけて「階層的」に書かれています。HTMLでは見出しを表現するために、見出し要素タグ`<h1>`〜`<h6>`が用意されています。また、Markdown記法では、\#の数が見出し要素タグのレベルに対応しており、容易に階層的な文章を書けます。\#を書くだけで、なんとなくドキュメントがうまく分割され、階層化されたように見えるというのが、Markdown記法人気の一つの理由なのではないかと思います。

階層構造は「インデント」をつけると視覚的にわかりやすくなります。たとえば、ソースコードも階層的に書かれていますが、関数レベルで眺めると、階層構造はインデントにより表現されています。また、エクスプローラーでフォルダを階層表示させるとツリー状に表示されますが、これもインデントをつけて表現されています。この発想に従えば、本来、文章全体にインデントをつけて各段落の階層の深さを表現したいところですが、残念ながらウェブを始め多くの文書は、物理的制約から縦長にならざるを得ません。そのため、文章全般に言えることですが、「本文にはインデントをつけずに、章、節、項、目や見出し要素タグで、どの程度のインデントなのかを視覚的に表現しなければならない」という命題を抱えています。
以下では、章、節、項、目や、h1、h2、h3といったインデントのレベルのことを「インデントの深さ」と表現します。

### HTMLでの課題

HTMLでは見出しのインデントの深さは、フォントサイズで視覚的に表現されています。たとえば、bootstrapではh1は36px、h2は30px、h3は26pxに設定されています。
フォントサイズによる表現は、異なる階層の見出しを比較することにより、直感的にインデントの深さを推測することができます。しかし、ページ内に見出しが一つしか表示されていない場合には比較ができないため、その見出しの階層がどの程度の深さなのかを知る術がありません。たとえば、26pxの見出しがh1なのかh2なのかh3なのかはわかりません。それを決めているのはcssなのですから。

そこで、通常は、頭の中でインデントの深さをバッファしながら読んでいかなければならず、本来必要のないメモリを脳内で消費していることになります。

また、見出し要素タグの表現では、残りの文章がどの程度残っているかを知る術がありません。特に最近のサイトでは、フッター部に広告や関連リンクが多く表示される傾向があり、スクロールの位置から文章の実質的な残りを推測することは困難です。

### 従来の解決策

こういった問題を解決するために、ヘッダー部に通し番号、例えば、1-1、1-2-1といった番号をつけることがあります。しかし、こういった数字は管理が困難であり、ヘッダーの並びが変わった場合にいちいち変更しなければなりません。かつ、スマホの縦長の画面では貴重な横方向のスペースを奪うことになってしまいます。そして、本来であれば、情報価値が低くなるはずの深い階層ほどたくさんの数字を必要としてしまうという矛盾を抱えています。

そもそも、私たちが欲しい情報は、連番ではなく、その進捗率(全体に対してどの程度進んでいるのか)なのです。そこで、ワード等で作成される一般的なドキュメントでは、全体のページ数に対する現在のページ数をフッター部に表示することが多いかと思います。これは大変便利な表記方法なのですが、ウェブではドキュメントのページに対応する概念がないため、残念ながら適用することができません。

### 今回提案する方法

そこで、こういった問題を解決するために、ドーナツチャートを多階層で表示するアイコンを用いて見出しのインデントの深さと進捗率を表現することを試みてみました。ドーナツチャートの階層はインデントの深さを、ドーナツチャートのパーセンテージは同一インデントの進捗を意味しています。

## デモ

[こちらです。](https://kenji0x02.github.io/donut-indent/sample.html#donut_indent_100_33_0)

## 使用方法

ソースコードはGithubで公開していますので、リポジトリ内の`donut-indent.js`を読み込んでください。
(https://github.com/kenji0x02/donut-indent)

また、jQueryも読み込んでください。

```html
<script src="https://code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
<script src="./donut-indent.js" type="text/javascript"></script>
```

すでにhtmlで書かれたドキュメントに適用する場合は以上で終了です。

marked.js等のmarkdownパーサーを導入すると、markdownを読み込んで表示することも可能です。
実際、このサンプルページでは、Gist上で書かれたmarkdownファイルをmarked.jsで読み込んだあと、ドーナツチャートのアイコンを挿入しています。この場合は、以下のようにデータを読み込んだあとで、`DonutIndent()`関数を呼び出す必要があります。

```html
<script>
$(document).ready(function(){
  var target = $("#markdown_content");

  $.ajax({
    url: target[0].attributes["src"].value,
  }).done(function(data){
    target.append(marked(data));
  }).fail(function(data){
    target.append("This content failed to load.");
  }).always(function(data){
    $.donutIndent({indentDepth: 3});
  });
});
</script>
```

なお、アイコン自体は、canvasで描画しています。

## 応用例

すでに勘のいい方はお気付きのように、こういった表示方法が有用なのはウェブに限定されていません。階層構造を持ったオブジェクト全般に適用することが可能です。そして、画面表示サイズが限られている、かつ、進捗率が大きな意味を持つ対象に適用すると効果が大きいです。
パワーポイントを用いたプレゼン資料や、電子書籍などが好例です。パワーポイントでは、進捗率を表示するために連番の数字を用いることが一般的ですが、上で述べたのと同じ課題を抱えています。
電子書籍については、従来は本の厚さに対する現在の位置により進捗率を把握していましたが、定期的にタイトルにアイコンを挿入することで進捗率の把握が簡単になるかもしれません。

## まとめ

* HTMLの文章構造をドーナツチャートで視覚化して、インデントの深さと進捗率を直感的に把握するツールを作ってみました
* このアプローチはスマートフォンとmarkdownが出会ったからこそ思いついた発想で、人類史上初（だと思う）
* 今後の展開に期待w