block by kcsluis 58202bc9497feed96369

Anscombe's Quartet

Full Screen

index.html

<!DOCTYPE html>
<meta charset="utf-8">

<style type="text/css">
	body {
		font-family: Arial, sans-serif;
		font-size: 9px;
		fill: #aaa;
		max-width: 960px;
		margin: 20px auto;
	}
	h1 {
		font-size: 32px;
		margin-left: 40px;
		margin-top: 20px;
	}
	.stats {
		margin-left: 40px;
		font-weight: bold;
	}
	.dataSpan {
		margin-right: 12px;
	}
	.circleLabel {
		fill: #333;
	}
	.axis path {
		display: none;
	}
	.axis line {
		stroke-width: 1px;
		stroke: #ccc;
		stroke-dasharray: 2px 2px;
	}
	.lineOfFit {
		stroke-width: 2px;
		stroke: lime;
	}
</style>

<body>
	<div class="stats"></div>
</body>

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

<script>

	var plotData = [
		{"x": 8,	"y": 6.58},
		{"x": 8,	"y": 5.76},
		{"x": 8,	"y": 7.71},
		{"x": 8,	"y": 8.84},
		{"x": 8,	"y": 8.47},
		{"x": 8,	"y": 7.04},
		{"x": 8,	"y": 5.25},
		{"x": 19,	"y": 12.5},
		{"x": 8,	"y": 5.56},
		{"x": 8,	"y": 7.91},
		{"x": 8,	"y": 6.80}
	];

	var xArray = plotData.map( function (d) { return d.x; });
	var xMean = (d3.mean(xArray)).toFixed(2);
	var xVar = (d3.variance(xArray)).toFixed(2);
	var yArray = plotData.map( function (d) { return d.y; });
	var yMean = (d3.mean(yArray)).toFixed(2);
	var yVar = (d3.variance(yArray)).toFixed(2);
	var statsData = [
		{"statType": "x Mean", "statData": xMean},
		{"statType": "y Mean", "statData": yMean},
		{"statType": "x Variance", "statData": xVar},
		{"statType": "y Variance", "statData": yVar},
	];

	var margin = {top: 40, right: 40, bottom: 40, left: 40};
	var width = 960 - margin.left - margin.right,
		height = 470 - margin.top - margin.bottom;

	// scale data
	var xScaled = d3.scale.linear()
		.range([0, width])
		.domain([0, 20]);
	var yScaled = d3.scale.linear()
		// clever reverse to account for SVG origin
		.range([height, 0])
		.domain([0, 16]);

	// add axes
	var xAxis = d3.svg.axis()
		.scale(xScaled)
		// using TICKS as the gridlines, genius!
		.tickSize(-height)
		.tickPadding(8)
		.orient("bottom");
	var yAxis = d3.svg.axis()
		.scale(yScaled)
		.tickSize(-width)
		.tickPadding(8)
		.orient("left");

	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 + ")");

	// add the scales
	svg.append("g")
		.call(xAxis)
		.attr("class", "axis")
		.attr("transform", "translate(0," + height + ")");
	svg.append("g")
		.call(yAxis)
		.attr("class", "axis");

	var intercept = 3;
	var slope = 0.5;
	var xMax = 20;

	svg.append("line")
		.attr("class", "lineOfFit")
		.attr("x1", xScaled(0))
		.attr("y1", yScaled(intercept))
		.attr("x2", xScaled(xMax))
		.attr("y2", yScaled(xMax*slope + intercept));

	var circleGroup = svg.selectAll("g.circleGroupCSS")
		.data(plotData)
		.enter()
		.append("g")
		.attr("class", "circleGroupCSS")
		.attr("transform", function (d) { 
			// pass xScaled function to scale
			// move whole group at once
			// the svg syntax is ("transform", "translate(x,y)")
			return "translate(" + xScaled(d.x) + "," + yScaled(d.y) + ")"; 
		});

	circleGroup.append("circle")
		.attr("r", 5)
		.attr("fill", "magenta")
		.attr("stroke", "white")

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


	// console.log(statsData);

	// var graphStats = d3.select("div.stats > span")
	// 	.data(statsData)
	// 	.enter()
	// 	.append("span")
	// 	.text( function (d) { return d.statType + ": " + d.statData });

	for (stat in statsData) {
		console.log(stat);
		d3.select("div.stats")
			.append("span")
			.attr("class", "dataSpan")
			.text( statsData[stat].statType + ": " + statsData[stat].statData );
	};

	// var graphStats = d3.select("div.stats")
	// 	.append("p")
	// 	.text("x Mean: " + xMean + " | y Mean: " + yMean + " | x Variance: " + xVar + " | y Variance: " + yVar);


</script>