xxxxxxxxxx
<html>
<body>
<h1>Let's make an Anscombe's scatter plot</h1>
<div class="buttons"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
font: 16px sans-serif;
}
.circle-label {
font: 12px sans-serif;
opacity: 0;
}
.buttons {
margin-bottom: 10px;
}
.title {
font: 20px sans-serif;
margin-bottom: 10px;
}
.y path {
fill: #efefef;
}
.axis line {
stroke: #bfbfbf;
stroke-dasharray: 1;
stroke-opacity: .5;
}
</style>
</body>
<script>
var margin = {top: 20, right: 10, bottom: 40, left: 40};
var width = 600 - 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 + ")");
var xScale = d3.scaleLinear()
.domain([0, 20])
.range([0, width]);
var yScale = d3.scaleLinear()
.domain([0, 20])
.range([height, 0]);
var xAxis = d3.axisBottom(xScale)
.tickSize(-height);
var yAxis = d3.axisLeft(yScale)
.tickSize(-width);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
svg.append("g")
.attr("class", "x axis")
.attr("transform","translate(0," + height + ")")
.call(xAxis)
d3.select(".y")
.select("text")
.remove()
var colorScale = d3.scaleSequential(d3.interpolateRainbow);
function dataSwap(datasetGroup) {
eachDataGroup = data.filter(function(d) { return d.group == datasetGroup })
eachDataGroup.sort(function(a, b) { return a.x - b.x });
svg.selectAll(".circleGroups")
.data(eachDataGroup)
.transition()
.delay(function(d, i) { return i*40; })
.attr("transform",function(d) { return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")" })
svg.selectAll(".circleGroups")
.select("circle")
.transition()
.delay(function(d, i) { return i*40; })
.style("fill", function(d, i) { return colorScale(i); })
d3.select(".title")
.text("Group " + datasetGroup)
}
d3.tsv("quartet.tsv", function(error, data) {
if (error) return console.warn(error);
window.data = data;
var groups = d3.set(data.map(function(d) { return d.group })).values();
d3.select(".buttons")
.selectAll("button")
.data(groups)
.enter().append("button")
.text(function(d) { return "Group " + d; })
.on("click", function(d) {
dataSwap(d);
})
groupOneData = data.filter(function(d) { return d.group == "I" })
groupOneData.sort(function(a, b) { return a.x - b.x });
colorScale.domain([0, groupOneData.length-1])
svg.append("text")
.attr("class", "title")
.attr("dy", -5)
.text("Group " + groupOneData[0].group)
var circleGroups = svg.selectAll(".circleGroups")
.data(groupOneData)
.enter().append("g")
.attr("class", "circleGroups")
.attr("transform",function(d) { return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")" })
.on("mouseenter", function(d) {
d3.select(this)
.append("text")
.attr("dx", 5)
.attr("dy", 10)
.text("(" + d.x + "," + d.y + ")")
d3.selectAll("circle")
.style("fill-opacity", .5);
d3.select(this)
.select("circle")
.transition()
.ease(d3.easeElastic)
.attr("r", 20)
.style("fill-opacity", 1);
})
.on("mouseleave", function(d) {
d3.select(this)
.select("text")
.transition()
.style("opacity", 0)
.transition()
.remove();
d3.select(this)
.select("circle")
.transition()
.ease(d3.easeElastic)
.attr("r", 10)
d3.selectAll("circle")
.style("fill-opacity", 1);
})
var radiusSize = 10;
circleGroups.append("circle")
.attr("r", radiusSize)
.style("fill", function(d, i) { return colorScale(i); })
})
</script>
https://d3js.org/d3.v4.min.js