自分用の備忘録

VimとかJSとか。やったことのメモ。自分のため。

D3.jsで地図を回転させる

前回まで弄っていた日本地図から少し離れ、今回は別の投影法を試してみます。

orthographic

D3.jsには、様々な投影法が用意されています。
その中でも今回はorthographicを使用してみます。
この投影法を使うと、地球儀みたいなものが作れちゃいそうです。 exampleはこちら

地図を描画し、回転させるところまでやってみます。

投影法の指定

前回の日本地図ではメルカトル図法を採用していました。
今回はこのような指定をします。

var projection = d3.geo.orthographic()
  .scale(200)
  .translate([w / 2, h / 2])
  .clipAngle(90)
  .rotate([x, y, z]);

d3.geo.orthographic()とした部分と、clipAngle()rotate()以外は前回と同じです。

clipAngle(度数)は、指定した角度分の陸地が見えるようなイメージです。
90と指定すると、90度分だけ描画されます。
180を指定すると、180度分描画されるので、裏側で見えないはずの陸地まで描画されます。
なかなか面白いことになります。

海に色をつける

陸地以外が白では味気ないので、海に色をつけてみます。
こちらを参考にさせていただきました。
ということで、地図を描画する前に円を描画しておきます。

svg.append('circle')
  .attr({
    cx: w / 2,
    cy: h / 2,
    r: 200,
    fill: '#333399'
  });

描画する

世界の地形データから、あらかじめtopojsonを作成しておきます。
あとは、日本地図の時と同じです。
マウスオーバーで国を赤で表示します。

var features = topojson(data, data.objects.world).features;

var earth = svg.selectAll('path')
  .data(features)
  .enter()
  .append('path')
  .attr({
    // いろいろ指定
  })
  .on({
    'mouseover': function () {
      // 処理
    },
    'mouseout': function () {
      // 処理
    }
  }); 

回転させる

ここまではほぼほぼ日本地図の時と同じです。
次は地図を回転させてみます。
d3.timer()使用し、一定時間ごとに処理させます。

d3.timer(function () {
  x += 5;
  y += 1;
  z += 1;
  projection.rotate([x, y, z]);
  earth.attr('d', path);
}, 500);

500ミリ秒毎に、xを+5、yとzを+1させるようにしてみました。
動きはしているのですが、どうもError: Invalid value for attribute d=""が出ているようで...。
まだ解決はできていません。つらみ。

作ったサンプル

次回は何をしよう。。。

D3.jsで地図にイベントをつける

先日の記事では日本地図をとりあえず描いてみました。
あれからちょいちょいと弄りまして、地図上にcircleを追加。
地図にマウスオーバーすると色を変えるようなことをしてみました。

イベントを追加する

イベントを追加する時には.on('event_name', function(){});のように追加します。
ここで、前回のコードからデータの指定部分を修正します。

var features = topojson.feature(data, data.objects.japan);

map_svg.appnend('path')
  .datum(features)
//以下略

前回は、`datum(features)``としていましたが、地図は描けていましたが、
この状態でイベントを追加しても、地図全体を指してしまい、上手くいきません。

append('path')で、一つのpath要素で描いている状態だったのだと思います。

修正

var features = topojson.feature(data, data.objects.japan).features;

map_svg.selectAll('path')
  .data(features)
  .enter()
  .appned('path')
// 以下略

topojson.feature(data, data.objects.japan)で取得できるオブジェクトのfeatreusの要素を取り出している感じです。

あとは以前と同じくattr({ })を指定し、その後でイベントを追加します。

// 略
.on('mouseover', function(){
  d3.select(this)
    .attr('fill', 'red');
})
.on('mouseout', function(){
  d3.select(this)
    .attr('fill', '#669966');
});

マウスオーバーされた時、都道府県が赤になります。
マウスアウトすると、元の色(#669966)に戻しています。

このthisがどうも、今回であればpathひとつひとつの要素を持っているような感じでした。

さらに地図にcircleなどを追加

していますが・・・。これは次回。

間違いなどあるかと思いますが、そこは申し訳ありません。

f:id:lisia:20140603211244p:plain

D3.jsで地図を描く

以前買った、インタラクティブ・データビジュアライゼーションはひとまず読了しました。
ちゃんと覚えたか?と問われれば、まだですが、少し感想を。

感想

D3.jsのチュートリアルの拡張のような内容で、
チュートリアルにある内容はもちろん、パイチャートやスタック、ジオコーディングまで、
幅広く基礎が学べる内容でした。

ページ数も250Pに及ばないぐらいで、調度良い分量でした。

さすがに1回では学びきれないので、少しずつ覚えていけたらと思っています。

そういえば、フォースレイアウトなんかも項目としてあって、すごく感動しました。
改めてD3.js使いこなせたらかっこよさそうと思いました。

Sample

いろいろ調べまして、日本地図の描画を行ってみました。
TopoJSONで地図を描くなど、googleとかいう素晴らしいサイトで検索すれば、
大体内容は同じです

コード

// width height
var w = 500,
    h = 400,

// projection
    projection = d3.geo.mercator()
      .center([139.5, 35.7])
      .translate([w/2, h/2])
      .scale([800]),

// path generator
    path = d3.geo.path()
      .projection(projection),

// svg
    svg = d3.select('body')
      .append('svg')
      .attr({
        'width': w,
        'height': h
      });

// json
d3.json('./japan.topojson', function(data){
  // features
  var features = topojson.feature(data, data.objects.japan);

  svg.append('path')
    .datum(features)
    .attr({
      'stroke': 'black',
      'stroke-width': '0.5',
      'd': path
    })
    .style('fill', '#669966');
});

w hは、そのまま横幅と高さに使います。
次にgeo系のやつです。projectionとpath。。
ちゃんと意味理解できてないので、そのうち。

そして、描画するエリアとして、svg要素を追加します。
d3.select('body')で、body要素を選択し、
.append('svg')で、svg要素を追加。
attrとして、横・縦を決めてやります。

d3.json()は、見たままですが、JSONを読み込みます。
他にはd3.csv()だとCSVなんか読み込めたりします。
いろいろあって便利です。

読み込んだデータを使って、 topojson.feature(data, data.objects.japan)で、フィーチャーを作成。
あとは似たようなことをしてます。
また要素追加→datumで今作ったフィーチャーを入れてやる。
attributes設定して、styleで・・・といった感じです。

すいません。今回は説明雑です。

Git扱えるようにと、Githubレポジトリ作って、サンプル公開してみました!
Gitもちゃんと扱えるようになりたいところです。本当に。

※記事書いてから、少しいじっているので、↑のコードではなくなっています 作ったサンプル

D3.jsのチュートリアルを少し

D3.jsとは

Data Driven Documentの頭文字をとって、D3のようです。

D3.js はデータに基づいてドキュメントを操作するための JavaScript ライブラリです。
D3 はHTML や SVGCSSを使ってデータに命を吹き込みます。D3は WEB 標準に重点を置いており、
強力な視覚化コンポーネントとデータドリブン (データ駆動型)DOM 操作手法の組み合わせにより、
特定のフレームワークに縛られることなく、モダンブラウザの性能をフルに 引き出すことができます。

データの視覚化を考える際、使いこなせると幸せになれそうなライブラリです。
公式のギャラリーを見るだけでも楽しいですので、一度見てみてください。 D3.js Gallery

チュートリアルの途中まで

以前、少しだけチュートリアルを進めていたのですが、記事にはしていなかったので、
今回記事としています。

チュートリアルを少し進めるだけで、比較的に簡単に、このようなグラフらしきものと円なんかが出力できたりします。

f:id:lisia:20140417031139p:plain

var dataset = [];
var h = 50;
var w = 500;
for(var i = 0; i < 25; i++){
  var newNumber = Math.random() * 25;
  dataset.push(newNumber);
}

d3.select("body").selectAll("div")
  .data(dataset).enter().append("div").attr("class", "bar")
  .style("height", function(d){
    var barHeight = d * 5;
    return barHeight + "px";
  });

var svg = d3.select("body").append("svg");
svg.attr("width", w).attr("height", h);

var circles = svg.selectAll("circle").data(dataset).enter().append("circle");
circles.attr("cx", function(d, i){
  return (i * 50) + 25;
}).attr("cy", h/2)
  .attr("r", function(d){
    return d;
  });

書いているjsのコードはこれだけです。 D3.jsのコードを綺麗に書けるようにもならないといけないです。これは汚すぎて読み辛い。
ちょっと各部分が何をしているのかは、記憶が曖昧なので、今回は省略しますが、
これから少しずつ覚えていきたいと思います。

データの視覚化

データを視覚化することは楽しいです。
単純にDBにデータ登録、編集、削除だけよりも、目に見えるというのはモチベーションも上がりますたぶん。

Vim

最近はVImでjazzが聴けるようになったので、作業が捗りそうです!
この話はまたそのうち。

OpenLayers3を触ってみる

お久しぶりの投稿です。
めちゃくちゃサボっておりました。
さて、今回のネタは地図です。

地図といえば

Google Maps APIなんかを使えば、比較的容易に地図を使ったアプリの作成が可能ですね。
あとは、好みに合わせてYahooやBingなんかもあります。

Google Mapsは便利ですが、ある一定ラインを超えると、課金対象となってしまいます。
怖いですね。
無料で使えるものはないのか…。

OpenLayers3

A high-performance, feature-packed library for all your mapping needs.

OpenLayers2を一から書き直した物だそうです。
OpenLayers3
OpenLayers3 example
exampleが豊富ですし、組み合わせで大体のことができそうですね!
exampleのanimationとか、ゲームとかでありそうな動きです。

Quick Start

Quick Startがサイトにあるので、そのコードでどうなるか試してみます。
script部分のみぬき出し。全部はサイト参照。

var map = new ol.Map({
  target: 'map',
  layers:[
    new ol.layer.Tile({
      source: new ol.source.MapQuest({layer: 'sat'})
    })
  ],
  view: new ol.View2D({
    center: ol.proj.transform([37.41, 8.82], 'EPSG:4326','EPSG:3857'),
    zoom: 4
  })
});

target:'map':地図を表示する場所の指定になります。
<div id='hoge'>なら、target:'hoge'といったような感じです。

layers:[new ol.layer.Tile({}):表示する地図のタイル指定ですね。
source:new ol.source.MapQuest({layer:'sat'}):タイルのソース指定でしょうか?

center:ol.proj.transform(....):表示した時の中心の指定ですね。
transformは座標の変換です。
zoomは言う必要もなく、ズームレベルの指定です。

表示してみる

f:id:lisia:20140310232233p:plain

このように衛生地図が簡単に表示できました。 地図の表示はすごく簡単!

終わりに

久しぶりの投稿でしたが、テスト投稿でもありました。
Markdown記法を覚えると良いと教えていただいたこともあり、Markdownを少し使いながら書いてみました。
覚えるまで時間がかかりそうだな。。。

またOpenLayers3について書けることがあれば、ちまちま書いてみようかと思います。
あ、Vimやらないと…。