A-frameとD3を組み合わせて使うサンプル。
localで動かしたいときは以下を。
$ git clone git@gist.github.com:2675d59f526a80b02d8db8c26ab0e45d.git
$ cd 2675d59f526a80b02d8db8c26ab0e45d
$ npm install
$ npm start
script.jsの中身を修正したい場合は、ビルドツールが使う依存モジュールのインストールが必要です。
$ npm run installDevtool
$ npm start
const poStrfy = (x, y, z) => [x, y, z].join(" ");
const cast = d => {
Object.keys(d).forEach(key => {
if (!isNaN(+d[key])) d[key] = +d[key];
});
return d;
};
//データの読み込み
d3.tsv("data.tsv", cast, main);
function main(data) {
//a-frameのscenエレメントにデータをバインド
const scene1 = d3.select("#scene1").datum(data);
//データの値をa-frameのhigth値に正規化する関数
scene1._scale = d3
.scaleLinear()
.domain([0, 400])
.range([0, 20])
.nice();
//a-frame Entityをd3を使って生成
scene1.call(addEntity);
}
function addEntity(_selection) {
//a-entity -> a-boxをsceneエレメントにバインドされた値から生成
var bar = _selection
.selectAll(".bar")
.data(d => d)
.enter()
.append("a-entity")
.attr("class", "bar")
.append("a-box")
.attr("class", (d, i) => "box box" + i)
.attr("color", "red")
.attr("position", (d, i) => {
return poStrfy(i * 1.1, -1, -5);
})
.attr("height", 0) //アニメーションの為に初期値を0としている
.on("mouseenter", function(d) {
bar.attr("color", "red");
d3.select(this).attr("color", "blue");
//d3でa-boxにバインドしたデータを取り出すことができる。
console.log(d);
});
// d3.jsのトランジション機能を使ってa-frameのエンティティをアニメーションさせる。
// 通常の.attrを使ったトランジションは補完値をあトリビュートに適用するループが呼ばれないため遷移しない。
// attrTweenを使い、明示的にトランジションループを回すことでa-frame側にアトリビュートの更新を反映することができる
bar
.transition()
.duration(2000)
.attrTween("height", (d, i) => {
var fn = d3.interpolate(0, _selection._scale(d["高さ"]));
return t => fn(t);
});
}
<!DOCTYPE html>
<title>d3 & a-frame example1</title>
<link href='dist.css' rel='stylesheet' />
<script src="//unpkg.com/d3@4.12.2/build/d3.min.js"></script>
<script src="//unpkg.com/aframe@0.7.1/dist/aframe.js"></script>
<body>
<a-scene id="scene1" d3>
<a-sky radius="5000" color="skyblue"></a-sky>
<a-plane color="wheat" height="20" width="40" position="0 -1 0" rotation="270 0 0"></a-plane>
<a-entity camera look-controls wasd-controls cursor="rayOrigin: mouse" position="6 0 5">
</a-entity>
</a-scene>
<script src='dist.js'></script>
</body>
年 建物名 高さ 階数
1935年 三越本店 60 7階
1936年 国会議事堂中央塔 65 9階
1964年 ホテルニューオータニ本館 73 17階
1968年 霞が関ビルディング 156 36階
1970年 世界貿易センタービル 163 40階
1971年 京王プラザホテル 179 47階
1974年 新宿住友ビル 210 52階
1974年 新宿三井ビル 225 55階
1978年 サンシャイン60 239.7 60階
1991年 東京都庁第一本庁舎 243 48階
1993年 横浜ランドマークタワー 296 70階
2014年 あべのハルカス 300 60階
/* Do not touch this file - your changes will be overwritten. */
!function(t){function n(i){if(c[i])return c[i].exports;var a=c[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}var c={};n.m=t,n.c=c,n.i=function(t){return t},n.d=function(t,c,i){n.o(t,c)||Object.defineProperty(t,c,{configurable:!1,enumerable:!0,get:i})},n.n=function(t){var c=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(c,"a",c),c},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=0)}([function(module,exports,__webpack_require__){"use strict";eval('\n\nvar poStrfy = function poStrfy(x, y, z) {\n\treturn [x, y, z].join(" ");\n};\n\nvar cast = function cast(d) {\n\tObject.keys(d).forEach(function (key) {\n\t\tif (!isNaN(+d[key])) d[key] = +d[key];\n\t});\n\treturn d;\n};\n\nd3.tsv("data.tsv", cast, main);\n\nfunction main(data) {\n\tvar scene1 = d3.select("#scene1").datum(data);\n\tscene1._scale = d3.scaleLinear().domain([0, 400]).range([0, 20]).nice();\n\tscene1.call(addEntity);\n}\n\nfunction addEntity(_selection) {\n\tvar bar = _selection.selectAll(".bar").data(function (d) {\n\t\treturn d;\n\t}).enter().append("a-entity").attr("class", "bar").append("a-box").attr("class", function (d, i) {\n\t\treturn "box box" + i;\n\t}).attr("color", "red").attr("position", function (d, i) {\n\t\tconsole.log(i);return poStrfy(i * 1.1, -1, -5);\n\t}).attr("height", 0).on("mouseenter", function (d) {\n\t\tbar.attr("color", "red");\n\t\td3.select(this).attr("color", "blue");\n\t\tconsole.log(d);\n\t});\n\n\tbar.transition().duration(2000).attrTween("height", function (d, i) {\n\t\tvar fn = d3.interpolate(0, _selection._scale(d["高さ"]));\n\t\treturn function (t) {\n\t\t\treturn fn(t);\n\t\t};\n\t});\n}//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9zY3JpcHQuanM/OWE5NSJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBwb1N0cmZ5ID0gKHgsIHksIHopID0+IFt4LHksel0uam9pbihcIiBcIik7XG5cblxuY29uc3QgY2FzdCA9IChkKSA9PiB7XG5cdE9iamVjdC5rZXlzKGQpLmZvckVhY2goa2V5ID0+IHtcblx0XHRpZighaXNOYU4oK2Rba2V5XSkpIGRba2V5XSA9ICtkW2tleV07XG5cdH0pO1xuXHRyZXR1cm4gZFxufVxuXG5kMy50c3YoXCJkYXRhLnRzdlwiLCBjYXN0ICwgbWFpbik7XG5cbmZ1bmN0aW9uIG1haW4oZGF0YSl7XG5cdGNvbnN0IHNjZW5lMSA9IGQzLnNlbGVjdChcIiNzY2VuZTFcIikuZGF0dW0oZGF0YSk7XHRcdFxuXHRzY2VuZTEuX3NjYWxlID0gZDMuc2NhbGVMaW5lYXIoKS5kb21haW4oWzAsIDQwMF0pLnJhbmdlKFswLCAyMF0pLm5pY2UoKTtcblx0c2NlbmUxLmNhbGwoYWRkRW50aXR5KTtcdFxufVxuXG5cbmZ1bmN0aW9uIGFkZEVudGl0eShfc2VsZWN0aW9uKXtcblx0dmFyIGJhciA9IF9zZWxlY3Rpb24uc2VsZWN0QWxsKFwiLmJhclwiKVxuXHRcdC5kYXRhKGQgPT4gZCApXG5cdFx0LmVudGVyKClcblx0XHQuYXBwZW5kKFwiYS1lbnRpdHlcIilcblx0XHQuYXR0cihcImNsYXNzXCIsIFwiYmFyXCIpXG5cdFx0LmFwcGVuZChcImEtYm94XCIpXG5cdFx0LmF0dHIoXCJjbGFzc1wiLCAoZCxpKSA9PiAgXCJib3ggYm94XCIraSApXG5cdFx0LmF0dHIoXCJjb2xvclwiLCBcInJlZFwiKVxuXHRcdC5hdHRyKFwicG9zaXRpb25cIiwgKGQsaSkgPT57Y29uc29sZS5sb2coaSk7IHJldHVybiBwb1N0cmZ5KGkgKiAxLjEsIC0xLCAtNSkgfSApXG5cdFx0LmF0dHIoXCJoZWlnaHRcIiwgMClcblx0XHQub24oXCJtb3VzZWVudGVyXCIsIGZ1bmN0aW9uKGQpe1xuXHRcdFx0YmFyLmF0dHIoXCJjb2xvclwiLCBcInJlZFwiKTtcblx0XHRcdGQzLnNlbGVjdCh0aGlzKS5hdHRyKFwiY29sb3JcIiwgXCJibHVlXCIpO1xuXHRcdFx0Y29uc29sZS5sb2coZClcblx0XHR9KVxuXHRcdFxuXHRiYXIudHJhbnNpdGlvbigpLmR1cmF0aW9uKDIwMDApXG5cdFx0LmF0dHJUd2VlbihcImhlaWdodFwiLCAoZCxpKSA9PiB7XG5cdFx0XHR2YXIgZm4gPSBkMy5pbnRlcnBvbGF0ZSgwLCBfc2VsZWN0aW9uLl9zY2FsZShkW1wi6auY44GVXCJdKSlcblx0XHRcdHJldHVybiB0ID0+IGZuKHQpIFxuXHRcdH0pXG59XG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHNjcmlwdC5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUFBO0FBS0E7QUFBQTtBQUVBO0FBQUE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=')}]);
{
"dependencies": {
"aframe": "^0.7.1",
"blockup": "^2.2.10",
"d3": "^4.12.2"
},
"name": "d3_aframe_sample1",
"description": "[Made with blockup](https://github.com/gabrielflorit/blockup)",
"version": "1.0.0",
"main": "dist.js",
"devDependencies": {},
"scripts": {
"start": "blockup",
"installDevtool": "cd node_modules/blockup/; npm install ; cd ../../",
"check": "blockup check",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
*
box-sizing border-box