D3 メモ[API]
API Reference
https://github.com/mbostock/d3/wiki/API-Reference
Event
<div id="container"> <button class="clickme">click me</button> <button class="clickme">click me</button> <button class="clickme">click me</button> <button class="clickme">click me</button> </div>
var data = [ { name: 'button1' }, { name: 'button2' }, { name: 'button3' }, { name: 'button4' } ]; d3.selectAll('.clickme') .data(data) .on('click', function(d, idx) { var posX = d3.event.pageX + 'px'; d3.select('#out') .style('left', posX) .text(function() { return d.name; }); }, false);
選択した要素にはonでイベントハンドラを登録できる。
イベントオブジェクトはグローバルなd3.eventを参照することで、対象の要素のイベントを取得できる。
イベントの発生時のマウス位置を、特定の要素内の相対位置で取得したい場合には
d3.mouse(document.getElementById('container'))のようにすると[x, y]の配列で取得できる。d3.touch()もある。
d3.selectAll('.clickme') .data(data) .on('click', function(d, idx) { var pos = d3.mouse(document.getElementById('container')); d3.select('#out') .text(function() { return d + ' at (' + pos[0] + ',' + pos[1] + ')'; }); }, false);
データ取得
- d3.xhr(url, callback)
- d3.text(url, callback)
- d3.json(url, callback)
- d3.xml(url, callback)
- d3.html(url, callback)
- d3.csv(url, callback)
サンプルなので、予め取得しておいたデータをjsonファイルとしてローカルに置いておく
http://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc&max-results=20&category=Music&format=5&orderby=rating&q=sonicyouth
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Demo</title> <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <style> .item { margin: 10px 0; } h5 { margin: 0; } ul { list-style: none; margin: 0; padding: 0; } .info { font-size: 85%; } </style> <script src="js/libs/d3/d3.v2.js" type="text/javascript"></script> <script src="js/libs/underscore-min.js" type="text/javascript"></script> <script src="js/app.js" type="text/javascript"></script> </head> <body onload="init();"> <div id="container"> <ul></ul> </div> </body> </html>
function init() { d3.json('data/videos.json', draw); } function draw(json) { d3.select('#container ul') .selectAll('li') .data(json.data.items) .enter() .append('li') .attr('class', 'item') .html(function(d, idx) { return buildHTML(d); }); } function buildHTML(d) { var tmpl = _.template( '<h5><%- title %></h5>' + '<img src="<%- thumbnail %>" />' + '<div class="info">' + '<span class="like"><%- like %></span> | ' + '<span class="view"><%- view %></span>' + '</div>' ); return tmpl({ title: d.title, thumbnail: d.thumbnail.sqDefault, like: d.likeCount, view: d.viewCount, }); }
配列操作
d3で扱うデータは配列が基本なので、配列操作のメソッドが色々用意されている。
function init() { d3.json('data/videos.json', draw); } // 欲しいデータだけ取り出す function initData(json) { return _.map(json.data.items, function(item) { return { title: item.title, fav: item.favoriteCount, view: item.viewCount, thumbnail: item.thumbnail.sqDefault }; }); } function draw(json) { var data = initData(json), fMax, fMin, split; // fav数の最小・最大値 fMax = d3.max(data, function(d) { return d.fav; }); fMin = d3.min(data, function(d) { return d.fav; }); // min/maxは一度に取得できる [min, max] fExtent = d3.extent(data, function(d) { return d.fav; }); // fav数の昇順ソート favAsc = data.sort(function(a, b) { return d3.ascending(a.fav, b.fav); }); // view数が10,0000以上のアイテムだけ取り出して降順にソート split = d3.merge(d3.split(data, function(d) { return d.view < 100000; })) .sort(function(a, b) { return d3.descending(a.view, b.view); }); }
d3.scale
fav数に対応した大きさの図形を描きたい時など
実際のデータの値のまま使うと
function init() { d3.json('data/videos.json', draw); } function initData(json) { return _.map(json.data.items, function(item) { return { title: item.title, fav: item.favoriteCount }; }); } function draw(json) { var data = initData(json); d3.select('#container') .selectAll('div') .data(data) .enter() .append('div') .attr('class', 'bar') .style('background', '#0088ff') .style('font-size', '12px') .style('height', '16px') .style('width', function(d) { return d.fav + 'px'; }) .text(function(d) { return d.title; }); }
fav数によっては、windowサイズを大きくはみ出してしまうので
例えば、最大でもwindow幅以内にして全データをスケールしたい場合にはScales APIを使う。
d3.scale.linear()
デフォルトで変域・範囲が0~1のスケールを作るので、必要な変域と、範囲を指定する
max = d3.max(data, function(d) { return d.fav; }); // 「0~fav数の最大値」を「0~windowサイズ」に収める w = d3.scale.linear() .domain([0, max]) .range([0, document.body.clientWidth]); d3.select('#container') .selectAll('div') .data(data) .enter() .append('div') .attr('class', 'bar') .style('background-color', '#0088ff') .style('font-size', '12px') .style('height', '16px') .style('width', function(d) { return w(d.fav) + 'px'; }) .text(function(d) { return d.title + ':' + d.fav + '(' + w(d.fav) + 'px)'; });
グラフの軸を描くときにも使える。