D3.js tips&tricks – D3のスケールとアニメーションで花火を打ち上げる

Share
d3_transition_wirework
画像をクリックすると実際のページが開きます。

 

目的:

D3で使えるいろいろな色スケールがどんなものかを見てもらうために、アニメーションを使った花火でデモを作ってみました。一発の花火ごとに使うスケールの種類が変わります。たとえば下のようにバラバラの色や、xやyの位置グラデーションを作ることができます。

解説:

値によって色を変えるスケールはいろいろあります。これが便利なのは、たくさんの色を割り振りたいときに、自動でやってくれるからです。
特に名目データを使うもののは、category10、category20、category20b、category20cなどがあります。これを使うと10個や20個の色を値ごとに設定してくれます。数字も名目とみなして使ってくれます。
量的なデータを使ったものでも色を変えられます。.range()の部分を色にすれば、値が2色の間で割り振ってくれます。

var color10 = d3.scale.category10();
color20 = d3.scale.category20(),
color20b = d3.scale.category20b(),
color20c = d3.scale.category20c(),
colors1 = d3.scale.linear()
				.domain([width/2 - 80, width/2 + 80])
				.range(["blue","red"]),
colors2 = d3.scale.linear()
				.domain([height/2 - 80, height/2 + 80])
				.range(["yellow","green"]);

コード:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<style>
	body {background: black; }
	</style>
</head>
<body>

	<script src="http://d3js.org/d3.v3.min.js"></script>

	<script>
	var width = 700,
	height = 500;

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

	var counter = 0;
	var durations = 2000;

	// 花火に使うカラースケール。
	var color10 = d3.scale.category10();
	color20 = d3.scale.category20(),
	color20b = d3.scale.category20b(),
	color20c = d3.scale.category20c(),
	colors1 = d3.scale.linear()
					.domain([width/2 - 80, width/2 + 80])
					.range(["blue","red"]),
	colors2 = d3.scale.linear()
					.domain([height/2 - 80, height/2 + 80])
					.range(["yellow","green"]);

	// 一回ごとにカラースケールを変えるためのリスト。
	var colorList = [color10,colors1,color20,colors2,color20b,color20c,];				

	// 初期のランダムデータ作成。
	var randomX = d3.random.normal(width/2, 80),
		randomY = d3.random.normal(height/2, 80);
	var data = d3.range(100).map(function() { return {x: randomX(), y: randomY()}; });

	// 初期の円。
	var circles = svg.selectAll("circle").data(data).enter()
					.append("circle")
					.attr({r:3,cx:width/2,cy:height/2,fill:"gray"});

	// インターバル一回ごとのアニメーション。
	function fireworks(){
		data = d3.range(100).map(function() { return {x: randomX(), y: randomY()}; });

		// カウンターを割った余りをインデックスにしてリストを回る。
		var roundedCount = counter%colorList.length;
		currentColor = colorList[roundedCount];
		counter = counter + 1;

		var firework = circles.data(data).transition().duration(durations)
				.attr("cx", function(d){ return d.x; })
				.attr("cy", function(d){ return d.y; })
				.attr("r", 10)
				.attr("fill", function(d){ return currentColor(d.x); });

				firework.transition().delay(durations).duration(durations)
				.attr({cx:width/2,cy:height/2,fill:"gray",r:3});
	}

	// 一定時間ごとにfireworksを実行。
	setInterval(fireworks,durations*2);

	</script>

</body>
</html>

コメントを残す