gpt4 book ai didi

javascript - 力模拟中气泡中的文本重叠

转载 作者:行者123 更新时间:2023-12-03 03:06:48 26 4
gpt4 key购买 nike

我有一个脚本,其中对气泡和气泡上的文本使用力模拟。对于某些气泡彼此靠近的数据,文本会重叠。我在模拟中使用了forceCollide,为什么文本仍然重叠?我的数据集实例的图像如下:

enter image description here

我的脚本如下:

//var margin = {top: 30, right: 20, bottom: 30, left: 50}

var margin = 40,
width = 600,
height = 400;

var xscale = d3.scaleLinear()
.domain([0, d3.max(data, function (d) {
return +d.student_percentile;
})])
.nice()
.range([0, width]);

var yscale = d3.scaleLinear()
.domain([0, d3.max(data, function (d) {
return +d.rank;
})])
.nice()
.range([height, 0]);

var svg = d3.select('.chart')
.classed("svg-container", true)
.append('svg')
.attr('class', 'chart')
.attr("viewBox", "0 0 680 490")
.attr("preserveAspectRatio", "xMinYMin meet")
.classed("svg-content-responsive", true)
.append("g")
.attr("transform", "translate(" + margin + "," + margin + ")");

simulation = d3.forceSimulation()
.force("x", d3.forceX(function(d) {
return xscale(+d.student_percentile);
}))
.force("y", d3.forceY(function(d) {
return yscale(+d.rank);
}))
.force("collide", d3.forceCollide(24));

var local = d3.local();
circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("opacity", 0.3)
.attr("r", 20)
.style("fill", function(d){
if(+d.admit_probability <= 40){
return "red";
}
else if(+d.admit_probability > 40 && +d.admit_probability <= 75){
return "yellow";
}
else{
return "green";
}
})
.on('mouseover', function(d, i) {
local.set(this, d3.select(this).style("fill"));
d3.select(this)
.transition()
.duration(1000)
.ease(d3.easeBounce)
.attr("r", 32)
.style("cursor", "pointer")
.attr("text-anchor", "middle");
var d = this.__data__;
show_details(d);
}
)
.on('mouseout', function(d, i) {
d3.select(this).style("fill", local.get(this));
d3.select(this).transition()
.style("opacity", 0.3)
.attr("r", 20)
.style("cursor", "default")
.transition()
.duration(1000)
.ease(d3.easeBounce);
remove_details();
});

texts = svg.selectAll(null)
.data(data)
.enter()
.append('text')
.attr("text-anchor", "middle")
.text(function(d) {
return d.abbreviation;
})
.attr("pointer-events", "none")
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("fill", "black");

simulation.nodes(data).on("tick", function() {
circles.attr("cx", function(d) {
return d.x = Math.max(20, Math.min(width - 20, d.x));
})
.attr("cy", function(d) {
return d.y = Math.max(20, Math.min(height - 20, d.y));
})
texts.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
});
});

我希望所有圆圈和文本不重叠。

最佳答案

问题出在这里:

.force("collide", d3.forceCollide(24)); 

您要为所有文本指定半径24,无论其大小如何。这是不正确的。半径应取决于文本的大小。

查看下面的演示。在这里,我使用 getCompulatedTextLength() 来获取文本的长度并设置新属性 (size)。然后,在模拟中,我使用该属性:

.force("collide", d3.forceCollide(function(d) {
return d.size
}))

这是演示:

var svg = d3.select("svg");
var data = [{
text: "some text"
}, {
text: "a longer text here"
}, {
text: "an even longer text here"
}, {
text: "short text"
}, {
text: "a long text"
}];
var texts = svg.selectAll(null)
.data(data)
.enter()
.append("text")
.text(function(d) {
return d.text
});
texts.each(function(d) {
d.size = this.getComputedTextLength() / 2
})
var simulation = d3.forceSimulation(data)
.force("center", d3.forceCenter(250, 150))
.force("collide", d3.forceCollide(function(d) {
return d.size
}))
.on("tick", tick);

function tick() {
texts.attr("x", function(d) {
return d.x;
}).attr("y", function(d) {
return d.y;
})
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="300"></svg>

关于javascript - 力模拟中气泡中的文本重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47132174/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com