SELECTED ENTRIES
CATEGORIES
ARCHIVES
SPONSORED LINK
MOBILE
qrcode
LINKS
PROFILE
OTHERS

08
--
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
31
--
>>
<<
--

Agata's Blog

MATLABやPythonとともにD3.jsを使ってデータ解析とデータビジュアライゼーションに挑戦する某エンジニアのBlog
<< 【D3.js】Chordダイアグラムの作成 | main | D3.jsのバージョンアップ >>
過去30日間に世界で発生した地震を可視化する その2
0
    以前このブログで、アメリカ地質調査所 (USGS: United States Geological Survey) の公開データをもとに、世界で過去30日間に発生したマグニチュード2.5以上の地震を可視化しました。今回はこのときのプログラムを改良して、特定地域で発生した地震のみをデータから抽出して表示できる、インタラクティブなウェブページを作ってみます。

    まず、基礎となるプログラムについては、以前の記事 (過去30日間に世界で発生した地震を可視化する) を参照して下さい。抽出したデータに従ってSVG要素を操作する方法については、「データの変化をSVG要素に反映する」を参考にして下さい。ツールチップの作成については、過去の記事 (ツールチップの作成方法) に詳しく紹介していますので、そちらもあわせて参照してもらえると、より理解が深まります。

    サンプルページ



    // 各ラジオボタン選択時に実行する関数
    function selectAll(){
        updateData("All");
    }
    
    function selectJapan(){
        updateData("Japan");
    }
    
    function selectAlaska(){
        updateData("Alaska");
    }
    
    function selectChile(){
        updateData("Chile");
    }
    
    function selectEcuador(){
        updateData("Ecuador");
    }
    
    // データ配列の初期化
    var dataSet = [];
    
    // X,Y軸を表示できるようにグラフの周囲にマージンを確保する
    var margin = {top: 40, right: 20, bottom: 40, left: 20};
    var width = 1200 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;
    
    // ツールチップ用の設定
    var div = d3.select("body")
      .append("div")
      .attr("class", "tooltip")
      .style("opacity", 0);
    
    // 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 time_scale;
    
    // 初期状態を描画
    d3.csv("./js/30Days_MagnitudeOver2.5.csv", function(error, dataSet){
      // CSVファイル内の時刻情報をJavaScriptのDate形式にパース
      var format = d3.time.format("%Y-%m-%dT%X.%LZ");
      time_start = new Date(format.parse(dataSet[0].time));
      time_end = new Date(format.parse(dataSet[dataSet.length - 1].time));
      // 時間軸のスケール関数を生成
      time_scale = d3.time.scale()
        .domain([time_start, time_end])
        .range([0, width]);
      // 地震の規模を楕円のサイズで表すためのスケール関数
      var r_scale = d3.scale.linear()
        .domain([0.0,10.0])
        .range([0.0, 200.0]);
      // 散布図を描画
      svg.selectAll("ellipse")
        .data(dataSet, function(d){
          return d.time;
        })
        .enter()
        .append("ellipse")
        .attr("rx", 0)
        .attr("ry", 0)
        .attr("cx", function(d,i){
          var tmp = new Date(format.parse(d.time));
          return time_scale(tmp);
        })
        .attr("cy", 150)
        .attr("stroke","#A0A0A0")
        .attr("fill", function(d,i){
          if (d.place == "Japan"){return "orange"}
          else{return "#D0D0D0"};
        })
        .on("mouseover", function(d){ // マウスオーバー時にツールチップを表示
          div.transition()
            .duration(500)
            .style("opacity", 1.0);
          div.html("Location: " + d.place + "
    Magnitude: " + d.mag) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseout", function(d) { // マウスアウトするとツールチップを非表示 div.transition() .duration(500) .style("opacity", 0.0); }) .transition() .delay(function(d,i){ return i*2; }) .attr("rx", 5) .attr("ry", function(d,i){ return r_scale(d.mag) }); // 時間軸を描画 svg.append("g") .attr("class", "axis") .attr("transform", "translate(0,320)") .call(d3.svg .axis() .scale(time_scale) .orient("bottom") .tickFormat(function(d,i){ var fmtFunc = d3.time.format("%b-%d"); return fmtFunc(d); }) ) .selectAll("text") .attr("transform", "rotate(45)") .attr("dy", 10) .attr("dx", 10) .style("text-anchor", "start"); }); // ラジオボタン選択時に実行する関数 function updateData(selecter){ d3.csv("./js/30Days_MagnitudeOver2.5.csv", function(error, dataSet){ // ラジオボタンで洗濯された地域のデータのみをCSVから抽出 if(selecter != "All"){ var dataSet = dataSet.filter(function(item, index){ if (item.place == selecter) return true; }); }; // CSVファイル内の時刻情報をJavaScriptのDate形式にパース var format = d3.time.format("%Y-%m-%dT%X.%LZ"); time_start = new Date(format.parse(dataSet[0].time)); time_end = new Date(format.parse(dataSet[dataSet.length - 1].time)); // 地震の規模を楕円のサイズで表すためのスケール関数 var r_scale = d3.scale.linear() .domain([0.0,10.0]) .range([0.0, 200.0]); // 散布図を描画 var ellipse = svg.selectAll("ellipse") .data(dataSet, function(d){ return d.time; }); ellipse.enter() .append("ellipse") .attr("rx", 0) .attr("ry", 0) .attr("cx", function(d,i){ var tmp = new Date(format.parse(d.time)); return time_scale(tmp); }) .attr("cy", 150) .attr("stroke","#A0A0A0") .attr("fill", function(d,i){ if (d.place == "Japan"){return "orange"} else{return "#D0D0D0"}; }) .on("mouseover", function(d){ // マウスオーバー時にツールチップを表示 div.transition() .duration(500) .style("opacity", 1.0); div.html("Location: " + d.place + "
    Magnitude: " + d.mag) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseout", function(d) { // マウスアウトするとツールチップを非表示 div.transition() .duration(500) .style("opacity", 0.0); }) .transition() .delay(function(d,i){ return i*2; }) .attr("rx", 5) .attr("ry", function(d,i){ return r_scale(d.mag) }); // データと紐づけされていないSVG要素を削除 ellipse.exit() .transition() .duration(1000) .attr("rx", 0) .attr("ry", 0) .remove(); }); };

     
    このエントリーをはてなブックマークに追加
    | 応用 | 00:15 | comments(0) | - | - |
    スポンサーリンク