Data is from the state data set.
Brush over points to reveal their values in an adjacent table.
forked from feyderm's block: Scatter plot + Brush
xxxxxxxxxx
<meta charset="utf-8">
<style>
text {
font-family: sans-serif;
fill: #000000;
}
table {
visibility: hidden;
position: absolute;
top: 30px;
left: 500px;
font-family: sans-serif;
font-size: 0.7em;
}
tr:nth-child(even) {
background-color: #d9d9d9;
}
.brushed {
opacity: 0.5;
}
.non_brushed {
opacity: 0.5;
}
</style>
<body>
<!--viz-->
<div id="chart"></div>
<!--table for data of brushed elements-->
<div id="table">
<table>
<tr>
<th>Pos</th>
<th>WT AA</th>
<th>Class</th>
<th>Structure</th>
</tr>
</table>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script type="text/javascript">
var margin = {top: 20, right: 0, bottom: 50, left: 85},
svg_dx = 500,
svg_dy = 400,
plot_dx = svg_dx - margin.right - margin.left,
plot_dy = svg_dy - margin.top - margin.bottom;
var x = d3.scaleLinear().range([margin.left, plot_dx]),
y = d3.scaleLinear().range([plot_dy, margin.top]);
var col = d3.scaleSequential(d3.interpolatePlasma);
var svg = d3.select("#chart")
.append("svg")
.attr("width", svg_dx)
.attr("height", svg_dy);
d3.csv("umap-embed.csv", d => {
var n = d.length;
var d_extent_x = d3.extent(d, d => +d.X),
d_extent_y = d3.extent(d, d => +d.Y),
d_extent_tol = d3.extent(d, d => +d.Tolerance);
x.domain(d_extent_x);
y.domain(d_extent_y);
col.domain(d_extent_tol);
var axis_x = d3.axisBottom(x),
axis_y = d3.axisLeft(y);
svg.append("g")
.attr("id", "axis_x")
.attr("transform", "translate(0," + (plot_dy + margin.bottom / 2) + ")")
.call(axis_x);
svg.append("g")
.attr("id", "axis_y")
.attr("transform", "translate(" + (margin.left / 2) + ", 0)")
.call(axis_y);
d3.select("#axis_x")
.append("text")
.attr("transform", "translate(360, -10)");
d3.select("#axis_y")
.append("text")
.attr("transform", "rotate(-90) translate(-20, 15)");
var circles = svg.append("g")
.selectAll("circle")
.data(d)
.enter()
.append("circle")
.attr("r", 5)
.attr("cx", (d) => x(+d.X))
.attr("cy", (d) => y(+d.Y))
.attr("class", "non_brushed")
.style("fill", (d) => col(+d.Tolerance));
function highlightBrushedCircles() {
if (d3.event.selection != null) {
// revert circles to initial style
circles.attr("class", "non_brushed")
.attr("r", 5)
.style("fill", (d) => col(+d.Tolerance));
var brush_coords = d3.brushSelection(this);
// style brushed circles
circles.filter(function (){
var cx = d3.select(this).attr("cx"),
cy = d3.select(this).attr("cy");
return isBrushed(brush_coords, cx, cy);
})
.attr("r", 7)
.attr("class", "brushed")
.style("fill", "black");
}
}
function displayTable() {
// disregard brushes w/o selections
// ref: https://bl.ocks.org/mbostock/6232537
if (!d3.event.selection) return;
// programmed clearing of brush after mouse-up
// ref: https://github.com/d3/d3-brush/issues/10
d3.select(this).call(brush.move, null);
var d_brushed = d3.selectAll(".brushed").data();
// populate table if one or more elements is brushed
if (d_brushed.length > 0) {
clearTableRows();
d_brushed.forEach(d_row => populateTableRow(d_row))
} else {
clearTableRows();
}
}
var brush = d3.brush()
.on("brush", highlightBrushedCircles)
.on("end", displayTable);
svg.append("g")
.call(brush);
});
function clearTableRows() {
hideTableColNames();
d3.selectAll(".row_data").remove();
}
function isBrushed(brush_coords, cx, cy) {
var x0 = brush_coords[0][0],
x1 = brush_coords[1][0],
y0 = brush_coords[0][1],
y1 = brush_coords[1][1];
return x0 <= cx && cx <= x1 && y0 <= cy && cy <= y1;
}
function hideTableColNames() {
d3.select("table").style("visibility", "hidden");
}
function showTableColNames() {
d3.select("table").style("visibility", "visible");
}
function populateTableRow(d_row) {
showTableColNames();
var d_row_filter = [d_row.Pos, d_row.WT_AA, d_row.Class, d_row.Struct];
d3.select("table")
.append("tr")
.attr("class", "row_data")
.selectAll("td")
.data(d_row_filter)
.enter()
.append("td")
.attr("align", (d, i) => i == 0 ? "left" : "right")
.text(d => d);
}
</script>
</body>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-scale-chromatic.v1.min.js