I'm fairly new to d3 and am wanting to create a visualization that will allow a user to check whether or not a device will be in range of a bluetooth speaker.
I was able to hack together most of what I want, but am not sure if I'm following d3 best practices. This will be eventually integrated with React. Any feedback on style/efficiency is appreciated.
(Note: you'll want to view in the full page)
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = 8,
unitRadius = 64;
var points = d3.range(10).map(function() {
return {
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius)
};
});
var circle = d3.range(1).map(function() {
return {
x: width / 2,
y: height / 2
};
});
var points = svg
.selectAll("circle.point")
.data(points)
.enter()
.append("circle")
.attr("class", "point")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", radius)
.style("fill", "red");
var circle = svg
.selectAll("circle.unit")
.data(circle)
.enter()
.append("circle")
.attr("class", "overlay")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", unitRadius)
.style("fill", "blue")
.call(
d3
.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)
);
function dragstarted(d) {
d3.select(this)
.raise()
.classed("active", true);
}
function dragged(d, i) {
d3.select(this)
.attr("cx", (d.x = d3.event.x))
.attr("cy", (d.y = d3.event.y));
var inside = d3.selectAll("circle.point").style("fill", function(p) {
var x = d.x - p.x;
var y = d.y - p.y;
var dis = Math.sqrt(x * x + y * y);
if (dis <= Math.abs(unitRadius - radius)) {
return "green";
} else {
return "red";
}
});
}
function dragended(d) {
d3.select(this).classed("active", false);
}
.overlay {
fill-opacity: 0.1;
}
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script>
<svg width="960" height="500"></svg>