|
<!DOCTYPE html> |
|
|
|
<html> |
|
<head> |
|
<title>Cleveland and McGill</title> |
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
|
|
|
|
|
<style> |
|
|
|
rect { |
|
|
|
cursor: pointer ; |
|
|
|
} |
|
|
|
</style> |
|
|
|
</head> |
|
<body> |
|
<h1>Elementary perceptual tasks</h1> |
|
<br> |
|
|
|
<div id='viz'></div> |
|
|
|
<h2>Cleveland and McGill, 1984</h2> |
|
|
|
|
|
|
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
|
|
<script> |
|
|
|
var data = [ 10, 5, 8]; |
|
|
|
var width = 1000, |
|
height = 400 |
|
noOfCharts = 4; |
|
|
|
var chartWidth = width / noOfCharts, |
|
barwidth = chartWidth/data.length - 20, |
|
barPadding = 20; |
|
|
|
var squareWidth = 10; |
|
|
|
var svg = d3.select("#viz").append("svg:svg") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
var y = d3.scale.linear() |
|
.range([height, 0]) |
|
.domain([0, d3.max(data, function(d) { return d; })]); |
|
|
|
/*var x = d3.scale.linear() |
|
.range(0, chartWidth);*/ |
|
|
|
var clickBoard = svg.append("svg:rect") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.style("fill", "white") |
|
.on("click", change); |
|
|
|
var squares = svg.selectAll("squares") |
|
.data(d3.range(250).map(function() { |
|
return { |
|
x: width * Math.random(), |
|
y: height * Math.random(), |
|
dx: Math.random() - .5, |
|
dy: Math.random() - .5, |
|
v: Math.random() * 10 |
|
}; |
|
})) |
|
.enter().append("svg:rect") |
|
.attr("width", squareWidth) |
|
.attr("height", squareWidth) |
|
.attr("fill-opacity", 0) |
|
.attr("x", function(d) { d.x += d.dx; if (d.x > width) d.x -= width; else if (d.x < 0) d.x += width; return d.x; }) |
|
.attr("y", function(d) { d.y += d.dy; if (d.y > height) d.y -= height; else if (d.y < 0) d.y += height; return d.y; }); |
|
|
|
|
|
|
|
|
|
|
|
////////////////////// |
|
|
|
|
|
|
|
shadingchartPosition = (chartWidth * 1) - chartWidth; |
|
|
|
var color = d3.scale.ordinal() |
|
.range(['#f7fbff','#deebf7','#c6dbef','#9ecae1','#6baed6','#4292c6','#2171b5','#08519c','#08306b']) |
|
.domain([2,3,4,5,6,7,8,9,10]); |
|
|
|
var shadingBars = svg.selectAll(".shadingBars") |
|
.data(data) |
|
.enter() |
|
.append("svg:rect") |
|
.attr("class", "shadingBars") |
|
.attr("x", function (d, i) { return shadingchartPosition + (i * barwidth) ; } ) |
|
.attr("y", function(d) { return y(10); }) |
|
.style("fill", function (d) { return color(d); } ) |
|
.attr("width", barwidth - barPadding) |
|
.attr("height", function(d) { return height - y(10); }); |
|
|
|
////////////////////// |
|
|
|
|
|
areaChartPosition = (chartWidth * 2) - chartWidth; |
|
|
|
var circleArea = d3.scale.sqrt().domain([2, 10]).range([5, 40]) |
|
|
|
var areaCircles = svg.selectAll(".areaCircles") |
|
.data(data) |
|
.enter() |
|
.append("svg:circle") |
|
.attr("class", "areaCircles") |
|
.attr("cx", areaChartPosition + (chartWidth/2) ) |
|
.attr("cy", function (d, i) {return (i * height/4) + 60 ;} ) |
|
.attr("r", function (d) { return circleArea(d) ;} ) ; |
|
|
|
////////////////////// |
|
|
|
pathchartPosition = (chartWidth * 3) - chartWidth; |
|
|
|
var paths = svg.selectAll(".paths") |
|
.data(data) |
|
.enter() |
|
.append("svg:path") |
|
.attr("d", function (d, i) { |
|
|
|
var startX = pathchartPosition + 20; |
|
var startY = (height - 20) - ((height/data.length) * i); |
|
var endX = pathchartPosition + chartWidth - 40; |
|
var endY = startY - 7*d; |
|
var path = ""; |
|
return path = "M" + startX + "," + startY + "L" + endX + "," + endY; |
|
|
|
}) |
|
.attr("stroke", "black") |
|
.attr("stroke-width",5 ) |
|
.attr("fill", "none");; |
|
|
|
|
|
////////////////////// |
|
|
|
barchartPosition = (chartWidth * 4) - chartWidth; |
|
|
|
|
|
var bars = svg.selectAll(".barchart") |
|
.data(data) |
|
.enter() |
|
.append("svg:rect") |
|
.attr("class", "barchart") |
|
.attr("x", function (d, i) { return barchartPosition + (i * barwidth) ; } ) |
|
.attr("y", function(d) { return y(d); }) |
|
.attr("width", barwidth - barPadding) |
|
.attr("height", function(d) { return height - y(d); }); |
|
|
|
|
|
////////////////////// |
|
|
|
var changeID = 1; |
|
var t = 1500; |
|
|
|
var smallScale = d3.scale.linear() |
|
.range([0, 30]) |
|
.domain([0, d3.max(data, function(d) { return d; })]); |
|
|
|
function change() { |
|
|
|
switch (true) |
|
{ |
|
|
|
case ( changeID === 1): |
|
|
|
paths |
|
.transition().duration(t) |
|
.style("stroke-opacity", 0); |
|
|
|
areaCircles |
|
.transition().duration(t) |
|
.style("fill-opacity", 0); |
|
|
|
|
|
|
|
break; |
|
|
|
case ( changeID === 2): |
|
|
|
shadingBars |
|
.transition().duration(t) |
|
.attr("width", squareWidth) |
|
.attr("height", squareWidth) |
|
.style("fill", "black") |
|
.style("fill-opacity", 0.8); |
|
|
|
bars |
|
.transition().duration(t) |
|
.attr("width", squareWidth) |
|
.attr("height", squareWidth) |
|
.style("fill-opacity", 0.8); |
|
|
|
squares |
|
.transition().duration(t) |
|
.delay(t) |
|
.style("fill-opacity", 0.8); |
|
|
|
break; |
|
|
|
|
|
case ( changeID === 3): |
|
|
|
shadingBars |
|
.transition().duration(t) |
|
.attr("height", function (d) { return smallScale(d) ;} ); |
|
|
|
bars |
|
.transition().duration(t) |
|
.attr("height", function (d) { return smallScale(d) ;} ); |
|
|
|
squares |
|
.transition().duration(t) |
|
.attr("height", function (d) { return smallScale(d.v) ;} ); |
|
|
|
break; |
|
|
|
case ( changeID === 4): |
|
|
|
shadingBars |
|
.transition().duration(t) |
|
.attr("height", squareWidth) |
|
.style("fill", function (d) { return color(Math.round(d)) ; } ); |
|
|
|
bars |
|
.transition().duration(t) |
|
.attr("height", squareWidth) |
|
.style("fill", function (d) { return color(Math.round(d)) ; } ); |
|
|
|
squares |
|
.transition().duration(t) |
|
.attr("height", squareWidth) |
|
.style("fill", function (d) { return color(Math.round(d.v)) ; } ); |
|
|
|
break; |
|
|
|
case ( changeID === 5): |
|
|
|
shadingBars |
|
.transition().duration(t) |
|
.attr("height", function (d) { return smallScale(d) ;} ) |
|
.attr("width", function (d) { return smallScale(d) ;} ); |
|
|
|
bars |
|
.transition().duration(t) |
|
.attr("height", function (d) { return smallScale(d) ;} ) |
|
.attr("width", function (d) { return smallScale(d) ;} ); |
|
|
|
|
|
squares |
|
.transition().duration(t) |
|
.attr("height", function (d) { return smallScale(d.v) ;} ) |
|
.attr("width", function (d) { return smallScale(d.v) ;} ); |
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
changeID++; |
|
|
|
}; |
|
|
|
|
|
</script> |
|
|
|
</body> |
|
</html> |