LATEST ENTRIES
CATEGORIES
ARCHIVES
SPONSORED LINK
MOBILE
qrcode
LINKS
PROFILE
OTHERS

11
--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
--
>>
<<
--

Agata's Blog

MATLABやPythonとともにD3.jsを使ってデータ解析とデータビジュアライゼーションに挑戦する某エンジニアのBlog
<< D3.js でギブス現象を見る | main | 【D3.js】 バラ曲線 (Rose curve) を描画する >>
【D3.js】 リサージュ曲線 (Lissajous curve) を描画する
0
    JUGEMテーマ:JavaScript

    前回は D3.js を使って、プルダウンメニューで選択した数値に従って変化するグラフを作成しました。今回はその応用として、リサージュ曲線 (Lissajous curve) を描画してみます。

    リサージュ曲線とは、x = cos(at), y = sin(bt)t を変化させたときに x-y 平面上に描かれる (x, y) の軌跡です。今回は 2 つのプルダウンメニューを用意して、a, b それぞれの数値をユーザが選択すると、画面上のリサージュ曲線がそれに従って変化するページを作ってみます。

    まず準備として、html ファイルに以下を追加します。ここでは D3.js で描画するグラフの線として、幅2ピクセルのオレンジ色の線を指定しています。また、プルダウンメニューとして a, b それぞれ 1 〜 10 まで選択可能としました。

    サンプルページ


     

    <style> 
      .line{ 
        fill: none; 
        stroke: orange; 
        stroke-width: 2px; 
      } 
    </style> 

    (中略)

    <p>
    a = <select id="listbox_a">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      <option value="4">4</option>
      <option value="5">5</option>
      <option value="6">6</option>
      <option value="7">7</option>
      <option value="8">8</option>
      <option value="9">9</option>
      <option value="10">10</option>
    </select>
    , b = <select id="listbox_b">
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      <option value="4">4</option>
      <option value="5">5</option>
      <option value="6">6</option>
      <option value="7">7</option>
      <option value="8">8</option>
      <option value="9">9</option>
      <option value="10">10</option>
    </select>
    </p>
    <svg id="MyGraph"></svg>


    ここで、対象となるプルダウンメニューを特定できるよう、id = "listbox_a", "listbox_b" として、それぞれのプルダウンに ID を設定しています。
    次に、プルダウンメニューで選択された a, b の値を取得して、リサージュ曲線を描画する D3.js プログラムを以下に示します。

    // X,Y軸を表示できるようにグラフの周囲にマージンを確保する
    var margin = {top: 40, right: 40, bottom: 80, left: 80};
    var width = 600 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;
    
    // SVGの表示領域を生成
    var svg = d3.select("#MyGraph")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
    
    var n = 800;
    
    var dt = 2.0*Math.PI/n;
    var t = d3.range(0, 2.0*Math.PI, dt);
    var x = d3.range(n);
    var y = d3.range(n);
    
    // X軸のスケール関数を生成
    var x_scale = d3.scale.linear()
      .domain([-1, 1])
      .range([(width/2) - 200, (width/2) + 200]);
        
    // Y軸のスケール関数を生成
    var y_scale = d3.scale.linear()
      .domain([-1,1])
      .range([(height/2) - 200, (height/2) + 200]);  
      
    // (x,y) の軌跡を描画するための関数
    var line = d3.svg.line()
      .x(function(d, i){ return x_scale(x[i]);})
      .y(function(d, i) { return y_scale(y[i]);})
      .interpolate("linear");
    
    var polyline = svg.append('path')
      .attr("class", "line")
      .attr('stroke', 'black')
      .attr('stroke-width', '1')
      .attr('fill', 'transparent');
    
    // 初期値として a = 1, b = 1のグラフを描画
    update(1,1);
    updateLine();
    
    // 対象となる html 内のプルダウン要素を選択 
    var select_a = document.getElementById( 'listbox_a' );
    var select_b = document.getElementById( 'listbox_b' );
    
    var a = 1;
    var b = 1;
    
    // プルダウンメニューが更新されるとグラフを更新する
    select_a.onchange = function(){
      // プルダウンで選択されているoption要素を取得する
      var selectedItem = this.options[ this.selectedIndex ];
      a = selectedItem.value;
      update(a, b);
      updateLine();
    }
    
    select_b.onchange = function(){
      // プルダウンで選択されているoption要素を取得する
      var selectedItem = this.options[ this.selectedIndex ];
      b = selectedItem.value;
      update(a, b);
      updateLine();
    }
    
    
    // リサージュ曲線 (Lissajous curve) を計算する
    function update(a, b){
      for (var i = 0; i < n; i++){
        x[i] = Math.cos(a*t[i]);
        y[i] = Math.sin(b*t[i]);
      }
    }
    
    // グラフを更新する
    function updateLine(){
      polyline
        .transition()
        .duration(300)
        .attr('d', line(y));
    }
    
    // X軸を描画
    svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(0," + height/2 + ")")
      .call(d3.svg
        .axis()
        .scale(x_scale)
        .orient("bottom")
      );
      
    // Y軸を描画
    svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(" + width/2 + ",0)")
      .call(d3.svg
        .axis()
        .scale(y_scale)
        .orient("left")
      );
    
    このエントリーをはてなブックマークに追加
    | アニメーション | 19:20 | comments(0) | - | - |
    スポンサーリンク