This page shows 55 points. 50 of them are placed randomly uniformly on the canvas. The remaining 5 are placed in a "cluster" somewhere on the canvas such that the expected density of the "cluster" is approximately 3 times higher than the density of the background noise. If you double click anywhere within the region that defines the "true" cluster, the cluster dots will turn red and will be ringed in red. If you miss, your "incorrect" guess region will be highlighted in blue.
Created
May 21, 2013 03:37
-
-
Save 8one6/5617335 to your computer and use it in GitHub Desktop.
Can you find the "true" cluster?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" | |
"http://www.w3.org/TR/html4/strict.dtd"> | |
<html lang="en"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<title>D3 Playground</title> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<link rel="stylesheet" type="text/css" href="style.css" /> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
function makeRandData(numPts) { | |
var myData = []; | |
for (var i = 0; i<numPts; i++) { | |
myData.push({ | |
"x" : Math.random(), | |
"y" : Math.random() | |
}); | |
} | |
return myData; | |
} | |
var clusterCx = Math.random(); | |
var clusterCy = Math.random(); | |
var clusterRad = 0.1; | |
function makeClusterData(cx, cy, numPts, radius) { | |
var myData = []; | |
for (var i = 0; i<numPts; i++) { | |
var radPct = Math.random(); | |
var rad = Math.sqrt(radPct * radius * radius); | |
var angle = 2 * Math.PI * Math.random(); | |
var x = cx + (rad * Math.cos(angle)); | |
var y = cy + (rad * Math.sin(angle)) | |
if (0 < x && x < 1 && 0 < y && y < 1) { | |
myData.push({ | |
"x" : x, | |
"y" : y | |
}); | |
} | |
} | |
return myData | |
} | |
var randData = makeRandData(50); | |
var clusterData = makeClusterData(clusterCx, clusterCy, 5, clusterRad); | |
var r = 4; | |
var pad = 30; | |
var h = 350; | |
var w = 350; | |
var th = h + (2*pad); | |
var tw = w + (2*pad); | |
var xScale = d3.scale.linear() | |
.domain([0,1]) | |
.range([pad,pad+w]); | |
var yScale = d3.scale.linear() | |
.domain([0,1]) | |
.range([pad+h,pad]); | |
var svg = d3.select("body").append("svg") | |
.attr("height", th) | |
.attr("width", tw); | |
var clusterCirclesGroup = svg.append("g"); | |
var clusterCircles = clusterCirclesGroup.selectAll("circle") | |
.data(clusterData) | |
.enter() | |
.append("circle") | |
.attr("cx", function (d,i) { return xScale(d.x) }) | |
.attr("cy", function (d,i) { return yScale(d.y) }) | |
.attr("r", r) | |
.attr("class", "dot"); | |
var randCirclesGroup = svg.append("g"); | |
var randCircles = randCirclesGroup.selectAll("circle") | |
.data(randData) | |
.enter() | |
.append("circle") | |
.attr("cx", function (d,i) { return xScale(d.x) }) | |
.attr("cy", function (d,i) { return yScale(d.y) }) | |
.attr("r", r) | |
.attr("class", "dot"); | |
var squareBackgroundGroup = svg.append("g"); | |
var squareBackground = squareBackgroundGroup | |
.append("rect") | |
.attr("x", 0) | |
.attr("y", 0) | |
.attr("height", th) | |
.attr("width", tw) | |
.attr("class", "squareBackground") | |
.on("dblclick", miss); | |
var clusterCircleOutlineGroup = svg.append("g"); | |
var clusterCircleOutline = clusterCircleOutlineGroup | |
.append("ellipse") | |
.attr("cx", xScale(clusterCx)) | |
.attr("cy", yScale(clusterCy)) | |
.attr("rx", w * clusterRad) | |
.attr("ry", h * clusterRad) | |
.attr("class", "clusterOutline") | |
.on("dblclick", hit); | |
function hit (d,i) { | |
clusterCircleOutline | |
.transition() | |
.style("opacity", 1) | |
.duration(1000) | |
clusterCircles | |
.transition() | |
.style("fill", "#F00") | |
.duration(1000) | |
} | |
function miss (d,i) { | |
var here = d3.mouse(this) | |
svg | |
.append("ellipse") | |
.attr("cx", here[0]) | |
.attr("cy", here[1]) | |
.attr("rx", 0) | |
.attr("ry", 0) | |
.attr("class", "miss") | |
.transition() | |
.attr("rx", h * clusterRad) | |
.attr("ry", w * clusterRad) | |
} | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
svg .dot { | |
fill: #B8DBFF; | |
stroke: #666; | |
} | |
svg .clusterOutline { | |
fill: rgba(255,255, 255, 0); | |
stroke: #F00; | |
stroke-width: 5; | |
opacity: 0.0; | |
} | |
svg .squareBackground { | |
fill: #F00; | |
opacity: 0.0; | |
} | |
svg .miss { | |
fill: #B8DBFF; | |
opacity: 0.5; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment