当我们没有碰撞/重叠时,我想在散点图的圆圈上显示标签。带标签的散点图的简单示例如下:
var width = 500;
var height = 500;
var margin = {
top: 40,
right: 40,
bottom: 40,
left: 40
};
var x = d3.scale.linear().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var minX = _(data).orderBy('x').first().x;
var maxX = _(data).orderBy('x').last().x;
x.domain([minX - 500, maxX + 500]);
y.domain([0, 100]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3
.select("#d3")
.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 + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + 0 + "," + height / 2 + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width / 2 + "," + 0 + ")")
.call(yAxis)
.append("text");
var gdots = svg.selectAll("g.dot")
.data(data)
.enter().append('g');
gdots.append("circle")
.attr("class", "dot")
.attr("r", function (d) {
return d.r;
})
.attr("cx", function (d) {
return x(d.x);
})
.attr("cy", function (d) {
return y(d.y);
})
.style("fill", function (d) {
return d.c;
});
gdots.append("text").text(function(d){
return d.name;
})
.attr("x", function (d) {
return x(d.x);
})
.attr("y", function (d) {
return y(d.y);
});
这个例子可以在小提琴上找到: https://jsfiddle.net/8e7qmzw8/1/
如何在给定示例中应用碰撞检测以显示非碰撞圆圈的标签?
答案 0 :(得分:0)
这是一种蛮力搜索方法:
gdots
// filter out those in a colliding state
.filter(function(d0, i){
var isCollide = false,
x0 = x(d0.x),
y0 = y(d0.y);
gdots.data().forEach(function(d1,j){
// if it has a collision with another, stop looking
if (!isCollide){
// if it's not itself
if (d0.name != d1.name){
var x1 = x(d1.x),
y1 = y(d1.y);
// if they overlap
isCollide = Math.pow((x1-x0),2) + Math.pow((y1-y0),2) <= Math.pow((d0.r+d1.r), 2);
}
}
});
return !isCollide;
})
.append("text").text(function(d){
return d.name;
});
运行代码:
var data = [
{"x": -123, "y": 63, "r": 37, "c": "#50C2E3", "name": "A"},
{"x": 71, "y": 0, "r": 15, "c": "#50C2E3", "name": "B"},
{"x": 3845, "y": 77, "r": 15, "c": "#50C2E3", "name": "C"},
{"x": 3176, "y": 90, "r": 15, "c": "#50C2E3", "name": "D"},
{"x": -17, "y": 56, "r": 15, "c": "#50C2E3", "name": "D"},
{"x": 1357, "y": 58, "r": 15, "c": "#50C2E3", "name": "E"},
{"x": 7684, "y": 75, "r": 15, "c": "#50C2E3", "name": "F"}
];
var width = 500;
var height = 500;
var margin = {
top: 40,
right: 40,
bottom: 40,
left: 40
};
var x = d3.scale.linear().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var minX = _(data).orderBy('x').first().x;
var maxX = _(data).orderBy('x').last().x;
x.domain([minX - 500, maxX + 500]);
y.domain([0, 100]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3
.select("#d3")
.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 + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + 0 + "," + height / 2 + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + width / 2 + "," + 0 + ")")
.call(yAxis)
.append("text");
var gdots = svg.selectAll("g.dot")
.data(data)
.enter().append('g');
gdots.append("circle")
.attr("class", "dot")
.attr("r", function (d) {
return d.r;
})
.attr("cx", function (d) {
return x(d.x);
})
.attr("cy", function (d) {
return y(d.y);
})
.style("fill", function (d) {
return d.c;
});
gdots
.filter(function(d0, i){
var isCollide = false,
x0 = x(d0.x),
y0 = y(d0.y);
gdots.data().forEach(function(d1,j){
if (!isCollide){
if (d0.name != d1.name){
var x1 = x(d1.x),
y1 = y(d1.y);
isCollide = Math.pow((x1-x0),2) + Math.pow((y1-y0),2) <= Math.pow((d0.r+d1.r), 2);
}
}
});
return !isCollide;
})
.append("text").text(function(d){
return d.name;
})
.attr("x", function (d) {
return x(d.x);
})
.attr("y", function (d) {
return y(d.y);
});
.node {
cursor: pointer;
}
.dot {
opacity: .7;
cursor: pointer;
}
.axis path,
.axis line {
fill: none;
stroke: rgb(31, 119, 180);
shape-rendering: crispEdges;
}
text {
stroke: none;
fill: #666666;
font-size: .6em;
font-family: "Helvetica Neue"
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.min.js"></script>
<div id="d3"></div>