block by kcsluis cfd6ce9a4a9e1263de5d

Enter, Update, Exit

Full Screen

index.html

<!DOCTYPE html>

<head>
	<meta charset="utf-8">
	<title></title>
	<style type="text/css">

	body {
		font-family: 'arial', sans-serif;
		font-size: 9px;
		width: 960px;
	}
	h1 {
		font-size: 24px;
	}
	.axis path {
		display: none;
	}
	.axis line {
		stroke-width: 1px;
		stroke: #ccc;
		stroke-dasharray: 2px 2px;
	}
	button {
		margin: 12px 12px 0px 0px;
	}
	circle.dot {
		fill: #000;
		stroke: #fff;
	}

	</style>
</head>

<body>

<h1></h1>

</body>


<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script>

// ENTER-UPDATE-EXIT PATTERN
	// 1. Make new data join
	// 2. Get rid of old elements
	// 3. Enter new elements
	// 4. Append elements as needed
	// 5. Update new selection

	// //bl.ocks.org/mbostock/3808218
	// //bost.ocks.org/mike/join/
	// //bost.ocks.org/mike/circles/

	// separating steps makes for cleaner, more maintainable code

var margin = {top: 6, right: 20, bottom: 20, left: 20};
var width = 960 - margin.left - margin.right,
		height = 400 - margin.top - margin.bottom;

var svg = d3.select("body").append("svg")
		.attr("width", width + margin.left + margin.right)
		.attr("height", height + margin.top + margin.bottom)
	.append("g")
		.attr("transform", "translate(" + margin.left + "," + margin.top + ")");


d3.tsv("ans_quart.tsv", function(error, data) {
	if (error) throw error;

	data.forEach( function (d) {
		d.x = +d.x;
		d.y = +d.y;
	});

	// add my buttons
	var allGroups = data.map( function (d) { return d.group; });
	var groupList = d3.set(allGroups).values();
	var buttons = d3.select("body").selectAll("button")
		.data(groupList)
		.enter()
		.append("button")
		.text( function (d) { return "Group " + d; })
		.on("click", function (d) {
			drawGroup(d);
		});

	// fixed domain for scales means consistent graph
	var xScaled = d3.scale.linear()
		.range([0, width])
		.domain([0, 20]);
	var yScaled = d3.scale.linear()
		.range([height, 0])
		.domain([0, 16]);

	var xAxis = d3.svg.axis()
		.scale(xScaled)
		.tickSize(-height)
		.tickPadding(8)
		.orient("bottom");
	var yAxis = d3.svg.axis()
		.scale(yScaled)
		.tickSize(-width)
		.tickPadding(8)
		.orient("left");

	var xAxisGroup = svg.append("g")
		.call(xAxis)
		.attr("class", "axis")
		.attr("transform", "translate(0," + height + ")");
	var yAxisGroup = svg.append("g")
		.call(yAxis)
		.attr("class", "axis");


	// graph drawing function
	function drawGroup (groupID) {

		var activeData = data.filter( function (d) { return d.group === groupID; });

		// xAxisGroup.call(xAxis);
		// yAxisGroup.call(yAxis);

		// 1. Make new data join
		var circleGroupData = svg.selectAll("g.circleGroup")
			.data(activeData);

		// 2. Get rid of old elements
		circleGroupData.exit().remove();

		// 3. Enter new elements
		var circleGroupEnter = circleGroupData
			.enter()
			.append("g")
			.attr("class", "circleGroup")
			.attr("transform", function (d) { 
				return "translate(" + xScaled(d.x) + "," + yScaled(d.y) + ")"; 
			});

		// 4. Append elements as needed
		circleGroupEnter.append("circle")
			.attr("class", "dot")
			.attr("r", 5);

		circleGroupEnter.append("text")
			.attr("class", "circleLabel")
			.attr("y", 3)
			.attr("x", 8)
			.text( function (d) { return (d.x).toFixed(1) + ", " + (d.y).toFixed(1) });

		// 5. Update new selection
		circleGroupData = svg.selectAll(".circleGroup")
			.transition()
			.duration(400)
			// explicitly telling it to transform is the key
			.attr("transform", function (d) { 
				return "translate(" + xScaled(d.x) + "," + yScaled(d.y) + ")"; 
			});

		// must use .select to maintain data join
		circleGroupData.select("text")
			.text( function (d) { return (d.x).toFixed(1) + ", " + (d.y).toFixed(1) });

		d3.select("h1")
			.text("Anscombe's Quartet — Group " + groupID);

		};

	var groupSelection = "I";
	drawGroup(groupSelection);

});

</script>

ans_quart.tsv

group	x	y
I	10	8.04
I	8	6.95
I	13	7.58
I	9	8.81
I	11	8.33
I	14	9.96
I	6	7.24
I	4	4.26
I	12	10.84
I	7	4.82
I	5	5.68
II	10	9.14
II	8	8.14
II	13	8.74
II	9	8.77
II	11	9.26
II	14	8.1
II	6	6.13
II	4	3.1
II	12	9.13
II	7	7.26
II	5	4.74
II	6	11
II	7	12
II	8	13
II	9	14
III	10	7.46
III	8	6.77
III	13	12.74
III	9	7.11
III	11	7.81
III	14	8.84
III	6	6.08
III	4	5.39
III	12	8.15
III	7	6.42
III	5	5.73
IV	8	6.58
IV	8	5.76
IV	8	7.71
IV	8	8.84
IV	8	8.47
IV	8	7.04
IV	8	5.25
IV	19	12.5
IV	8	5.56
IV	8	7.91
IV	8	6.89