17:高度なデータ(Advanced Data)

保存されたJSONの読み込み

Bubbleクラスを作成し、JSONファイルからのデータを使って、複数の泡(バブル)をインスタンス化し、結果を画面に表示します。Webブラウザがファイルを保存する場所はブラウザによって異なるので、Processingのサンプルで使っているsaveJSONは利用しません。Daniel ShiffmanのLoadSaveJSONサンプルにもとづく。

sketch.js

let data = {}; // loadJSON()呼び出しからの結果を保持するグローバルオブジェクト
let bubbles = []; // ずべてのBubbleオブジェクトを保持するグローバル配列

// 'setup()'の実行前に完了させるため、非同期データの読み込みをpreload()内に置く
function preload() {
    data = loadJSON('assets/bubbles.json');
    print(data);
}

function setup() {
    createCanvas(640, 360);
    loadData();
}

function draw() {
    background(255);

    // 全Bubbleオブジェクトを表示
    for (let i = 0; i < bubbles.length; i++) {
        bubbles[i].display();
        bubbles[i].rollover(mouseX, mouseY);
    }

    // 下部にテキスト表示
    textAlign(LEFT);
    fill(0);
    text('Click to add bubbles.', 10, height - 10);
}

// 保存されたBubbleデータをBubbleオブジェクトに変換する
function loadData() {
    let bubbleData = data['bubbles'];
    print(bubbleData);
    for (let i = 0; i < bubbleData.length; i++) {
        // 配列内の各オブジェクトを取得
        let bubble = bubbleData[i];
        // positionオブジェクトを取得
        let position = bubble['position'];
        // positionからxとyを取得
        let x = position['x'];
        let y = position['y'];

        // 直径(数値)とラベル(文字列)を取得
        let diameter = bubble['diameter'];
        let label = bubble['label'];

        // JSONデータから得た情報を使ってBubbleオブジェクトを作成し、bubbles配列に追加する
        bubbles.push(new Bubble(x, y, diameter, label));
    }
    print(bubbles);
}


// マウスがクリックされるたびに新しいBubbleオブジェクトを作成する
function mousePressed() {
    // 新しいBubbleオブジェクトの作成に必要な直径とラベル
    let diameter = random(40, 80);
    let label = 'New Label';

    // 新しいJSON Bubbleオブジェクトを配列に追加
    bubbles.push(new Bubble(mouseX, mouseY, diameter, label));

    // 多すぎる場合には、数を減らす
    if (bubbles.length > 10) {
        // 配列から最初のアイテムを削除
        bubbles.shift();
    }
}

Bubble.js

// Bubbleクラス
class Bubble {
    constructor(x, y, diameter, name) {
        this.x = x; // x位置
        this.y = y; // y位置
        this.diameter = diameter; // 直径
        this.radius = diameter / 2; // 半径
        this.name = name; // 名前

        this.over = false; // マウスと重なっているかどうか
    }

    // マウスがこのオブジェクトに重なっているかどうか
    rollover(px, py) {
        // 送られて来るpx, py(= mouseX, mouseY)とこのオブジェクトとの距離
        let d = dist(px, py, this.x, this.y);
        // 距離がこのオブジェクトの半径より小さければ重なっているので、overはtrue
        // そうでなければoverはtrue
        this.over = d < this.radius;
    }

    // 表示
    display() {
        stroke(0);
        strokeWeight(0.8);
        noFill();
        ellipse(this.x, this.y, this.diameter, this.diameter);
        // マウスと重なっているなら
        if (this.over) {
            // 白い文字で名前を描画する
            fill(0);
            textAlign(CENTER);
            text(this.name, this.x, this.y + this.radius + 20);
        }
    }
}
解説

プログラム、またはアプリケーションにとってデータは重要です。たとえば天気予報アプリにとって、地域とそれに関連付けた天気予報のデータは必須です。

アプリが必要とするデータはアプリ内部に保持することもできます。たとえば年賀状アプリなどは、個人情報保護の観点からも、内部に隠した方が安全でしょう。

一方、データを外部に置いて、必要に応じてアプリに読む込むようにすると、アプリのコードに手を加えず、外部データを修正するだけで、アプリに変更を加えることができます。簡単な例で言うと、Webページの背景色を外部CSSファイルで設定しておくと、そのCSSファイルを修正するだけで、Webページに何ら手を加えることなく、その背景色が変更できます。

天気予報アプリなどを作成するときには、当然、外部データを読み込む仕様で着手するでしょうが、そうでないアプリでも、下図のように、データを着脱式のモジュールのように考えると、後々のメンテナンスが楽になります。

p5.jsにおけるJSONデータの扱いについては「11_2:JSONデータ p5.js JavaScript」で述べています。またExcelファイルのデータをCSV形式で書き出したCSVデータの扱いについては「11_1:表データ p5.js JavaScript」で述べています。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA