スコット・マレイ
コード・アーティスト

Tutorials > D3 > データ型

データ型

最終更新日 2012年12月30日(原文)  2013年04月09日(翻訳 / h.sakai

D3 には入力データの扱いに関して極めて高い柔軟性があります。この章では JavaScript と D3 で一般的に使われるデータ構造について解説します。

変数

変数とは一個のデータであり、データの最小構成要素です。変数はすべてのデータ構造の基本であり、他の様々なデータ構造も、単に変数の組み合わせのバリエーションに過ぎません。

JavaScript 初学者の方は、まず、この言語が型付けのゆるい言語であることを憶えてください。変数にどのようなの情報が格納されるのかを、前もって宣言する必要がないのです。Java 等の他の多くの言語では、intfloatbooleanString 等、変数を型宣言してから使う必要があります。ちなみに Java と JavaScript はまったく異なる言語です!

// Java の変数宣言
int number = 5;
float value = 12.3467;
boolean active = true;
String text = "Crystal clear";

一方 JavaScript は、代入された情報の種類に基づいて自動的に変数を型付けします( なお JavaScriptでは、文字列を囲むのに ''"" のどちらを使ってもかまいません。私はダブルクォーテションマーク "" を使いますが、シングルクォーテーションマーク '' を好む人もいます)。

// JavaScript の変数宣言
var number = 5;
var value = 12.3467;
var active = true;
var text = "Crystal clear";

var、var、var、の嵐に多少うんざりしますが、何が入るのかも分からないうちに変数を宣言し命名できるのは便利です。また、変数のデータ型を有無も言わさずその場で変更することもできます。

var value = 100;
value = 99.9999;
value = false;
value = "これはたぶん駄目だろう";
value = "あれ?うまくいった!問題なし!";

配列

配列とは、複数の値をまとめ、一つの変数に格納したものです。

関連のある値を別々の変数で管理するのは効率の良い方法とは言えません。

var numberA = 5;
var numberB = 10;
var numberC = 15;
var numberD = 20;
var numberE = 25;

関連した値は一つの配列にまとめるほうがずっとシンプルです。値を囲った角カッコ [] が配列であることを示し、配列内の値はカンマによって区切られます。

var numbers = [ 5, 10, 15, 20, 25 ];

データの視覚化では、配列はいたるところに登場してきますので、すぐにお馴染みの存在になるでしょう。配列の値にアクセスする(値を取り出す)にはカッコ記法を用います。

numbers[2]  // 15を返す

角カッコ内の数値は配列内の値の位置を示しています。配列の位置は 0 から数えます。つまり最初の位置が 0、2 番目の位置が 1、以下同様です。

numbers[0]  // 5 が返る
numbers[1]  // 10 を返す
numbers[2]  // 15 を返す
numbers[3]  // 20 を返す
numbers[4]  // 25 を返す

配列を二次元の表と考えれば理解しやすいかもしれません。つまり、表計算シートのように行と列で考えるのです。

 ID | 値
------------
0  |  5
1  |  10
2  |  15
3  |  20
4  |  25

配列に入れられるのは整数だけではありません。どんなデータ型でも大丈夫です。

var percentages = [ 0.55, 0.32, 0.91 ];
var names = [ "田中", "鈴木", "渡辺" ];

percentages[1]  // 0.32 が返る
names[1]        // "鈴木" が返る

配列と FOR ループの親密な関係

もし配列と強力な for ループの存在がなければ、プログラミングによるデータ視覚化もそう簡単な作業ではなくなるでしょう。両者は、データマニアにとっての手足そのものです(「データマニア」になった覚えがないという方はこの章のタイトルを見返してください。この章は「データ型」についての章です!)(※訳注:「データ型」の原題 "Type of Data" の "type of ~" には「~の典型(的人物)」の意味がある)。

まず配列が多くのデータを一カ所にまとめ、次に for() がすばやくすべての値をループして何らかの処理を行います。たとえば、その値をヴィジュアルな形で表示することです。D3 はしばしば、魔法の data() メソッドを使うことで暗黙のうちにループを実行します。しかし、まずは自分自身でループ処理を書けるようになることが重要です。

for() ループの詳細には立ち入りません。それだけで優に一本のチュートリアルが必要になるからです。ここでは次の例だけ記憶にとどめておいてください。上述の配列 numbers をループします。

for (var i = 0; i < numbers.length; i++) {
   console.log(numbers[i]);  // コンソールに値を表示する
}

一行目の numbers.length に注目してください。ここがループの最も美しい箇所です。numbers の要素が10個ならループは 10 回まわり、一千万個でも…、やはり要素の個数だけ回ります。コンピュータが最も優れているのはこの点で、一つの命令群を与えるだけで、何度でも繰り返しそれを実行します。これはまた、データ視覚化が最も価値を発揮する点でもあります。一度視覚化システムのデザインとプログラム作れば、どのようにデータを変化させても、システムはそれに応じて結果を表示します。データは一回一回異なっていても、システムのマッピングルールは常に一貫しているのです。

オブジェクト

単純な値のリスト用途であれば配列でも充分ですが、複雑な構造のデータを扱う場合にはオブジェクトの方が適しています。データ視覚化という用途に限れば、JavaScript のオブジェクトとは独自のデータ構造の入れ物であると理解してかまいません。波カッコ {} がオブジェクトであることを示し、カッコの間に、プロパティの組を並べます。プロパティと値の間はコロンで区切り、プロパティと値の組同士の間はカンマで区切ります。最後の組の後にカンマは不要です。

var fruit = {
   kind: "ぶどう",
   color: "赤",
   quantity: 12,
   tasty: true
};

値を参照するにはドット表記を使います。ドットの後にプロパティを指定します。

fruit.kind      // "ぶどう" を返す
fruit.color     // "赤" を返す
fruit.quantity  // 12 を返す
fruit.tasty     // true を返す

オブジェクトの値とは、オブジェクトの種類や性質のようなものだと考えてください。おや、こんなところに果物があるぞ?「この果物の種類( kind )は何だろう?」。答えは「fruit.kind"ぶどう"です」。「こいつはおいしい( tasty )かな?」。もちろんです。なぜなら「fruit.tastytrue」だからです。

オブジェクト+配列

配列とオブジェクトを組み合わせることもできます。オブジェクトの配列、配列のオブジェクト、オブジェクトのオブジェクト、その他、基本的に自分のデータセットの構造を反映させる、どのような組み合わせを作ってもかまいません。

ぶどうのほかに、もう二種類果物を扱うことになったとしましょう。今度は複数の果物を扱える構造が必要です。まず一番外側に、オブジェクトを入れるための配列を角カッコ [] を使って作ります。その中に、それぞれ果物をあらわすオブジェクトを波カッコ {} を使って作って行きます。オブジェクト内には、オブジェクト表記に従ってプロパティと値の組み合わせを記述します。各オブジェクトの間はカンマで区切ります。

var fruits = [
   {
      kind: "ぶどう",
      color: "赤",
      quantity: 12,
      tasty: true
   },
   {
      kind: "キウイ",
      color: "茶色",
      quantity: 98,
      tasty: true
   },
   {
      kind: "バナナ",
      color: "黄色",
      quantity: 0,
      tasty: true
   }
];

データにアクセスするにはインデックスとプロパティをたどって行くだけです。[] が配列、{} がオブジェクトの意味であることを忘れないようにしましょう。fruits は配列ですから、まずカッコ記法を使って配列のインデックスを指定します。

fruits[1] // キウイのオブジェクトを返す

fruits 配列の各要素はオブジェクトですから、次にドット記法でプロパティを指定します。

fruits[1].quantity   // 98 を返す

オブジェクトの配列 fruits のすべての値を表示させてみましょう。

fruits[0].kind      ==  "ぶどう"
fruits[0].color     ==  "赤"
fruits[0].quantity  ==  12
fruits[0].tasty     ==  true

fruits[1].kind      ==  "キウイ"
fruits[1].color     ==  "茶色"
fruits[1].quantity  ==  98
fruits[1].tasty     ==  true

fruits[2].kind      ==  "バナナ"
fruits[2].color     ==  "黄色"
fruits[2].quantity  ==  0
fruits[2].tasty     ==  true

OK です。たとえばバナナの本数は fruits[2].quantity 本となります。

JSON

D3 の経験を積んでいくうちに、どこかで出あうことになるのが JSON( ジェイソン、JavaScript Object Notation )です。詳しい説明はWikipedia をご覧いただくとして、JSON とは基本的に、データを JavaScript のオブジェクトと同じ記法で表現するための構文のことです。その構文は、(当然のことながら)JavaScript や AJAX リクエストでの利用に最適化されており、それが WEB ベースの API の多くが JSON 形式でデータを吐き出す理由でもあります。JSON は XML よりも高速かつ簡単に解析可能です。もちろん、JavaScript のライブラリである D3 との相性も優れています。

JSON の見た目は、 JavaScript のオブジェクトと比べ、それほど違いはありません。

var jsonFruit = {
    "kind": "ぶどう",
    "color": "赤",
    "quantity": 12,
    "tasty": true
};

この例での唯一の相違点は、JSON ではプロパティもダブルクォーテーション "" で囲まれた文字列となっていることだけです。

GeoJSON

JSON が既存の JavaScript オブジェクト構文の一形式であるのに過ぎないのと同様に、GeoJSON も、地理データを格納するのに最適化された、 JSON オブジェクト構文の一形式に過ぎません。GeoJSON オブジェクトはすべて JSON オブジェクトであり、JSON オブジェクトはすべて JavaScript オブジェクトなのです。

GeoJSON には、地理空間上の点(一般的には緯度・経度座標)だけではなく、直線やポリゴン等のシェイプやその他の空間的フィーチャーを格納することができます。大量の地理情報を D3 で扱う場合は、一度 GeoJSON フォーマットに変換することを検討する価値はあるでしょう。

GeoJSON の詳細については地理マップの解説時にあらためて触れることにして、ここでは簡単な GeoJSON データの例を載せておきます。

var geodata = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [ 150.1282427, -24.471803 ]
            },
            "properties": {
                "type": "town"
            }
        }
    ]
};

(紛らわしいですが、経度を緯度より先に書くのが規則です。経度・緯度表記に慣れるようにしましょう。)

次章は棒グラフの作成

インタラクティブ・データ・ヴィジュアライゼーション このチュートリアルの書籍版の翻訳がオライリー・ジャパンより発売されました。タイトルは『インタラクティブ・データビジュアライゼーション ―D3.jsによるデータの可視化』です(画像をクリックするとアマゾンに飛びます)。

このチュートリアルを大幅に拡充し、3倍近い内容となっています。JavaScriptを中心に基礎編をさらに詳しく解説し(書籍版第3章)、応用編としてモーション、イベント、レイアウト、地図の作成法、データのエクスポート(PDFやSVG等)の章が追加されています(同9章~13章)。アマゾンのページで目次を見ることができます。

本チュートリアルがわかりにくいと感じられた方、あるいは本チュートリアルを終え、さらに応用力を身につけたいと思われた方のどちらにもお勧めの内容となっています。

翻訳はコンピュータ・プログラミング関連書籍を多数翻訳されている長尾高弘氏です。