d3.js力模拟实现不同半径beeswarm蜂群图的x轴点偏移问题咨询
问题排查及修复方案
经排查,偏移问题由多处配置错误共同导致,对应修复方案如下:
核心错误点
- 多余的全局居中力干扰节点位置
你配置的d3.forceCenter(width / 2, height/2)会将所有节点的整体中心强制拉到画布正中间,直接覆盖了forceX给每个节点设置的x方向目标位置,这是偏移的核心原因,该配置完全不需要,直接删除即可。 - X轴位置和节点不匹配
d3.axisBottom默认渲染在y=0的位置(也就是你当前svg的最顶部),你没有给x轴容器添加向下平移的变换,自然和下方的节点x坐标对应不上,需要给x轴容器添加位移属性,移动到画布底部。 - y方向配置紊乱间接影响对齐
你给节点初始化的y值为height + Math.random(),已经超出了画布范围,且没有明确y方向的统一目标位置,导致节点排布紊乱,间接干扰x方向对齐效果。 - X轴比例尺冗余计算引入偏差
你已经提前计算width为画布宽度减去左右margin的值,x比例尺的range直接设置为[0, width]即可,不需要额外再减margin.right,多余的计算会导致x坐标映射出现偏差。
修正后的关键代码片段
// 1. 修正x比例尺,可同步调整domain最小值避免左侧空白 var x = d3.scaleLinear() .domain([d3.min(features, tp)/100, d3.max(features, tp)/100]) .range([0, width]) // 没用的y比例尺可以直接删除 var r = d3.scaleSqrt().domain([0, d3.max(features, pop_mun)]) .range([0, 25]); // 2. 修正x轴位置,移动到画布底部 var xAxis = d3.axisBottom(x).ticks(20) .tickFormat(formatPercent); svg.append("g") .attr("class", "x axis") .attr("transform", `translate(0, ${height})`) .call(xAxis); // 3. 修正节点初始y值,设在垂直中心附近 var nodes = features.map(function (node, index) { return { radius: r(node.properties.pop_mun), color: '#ff7f0e', x: x(node.properties.tp60 / 100), y: height/2 + Math.random() * 10, pop_mun: node.properties.pop_mun, tp60: node.properties.tp60 }; }); // 4. 修正力模拟配置,删掉多余配置 const NUM_ITERATIONS = 1000; var force = d3.forceSimulation(nodes) .force('charge', d3.forceManyBody().strength(-3)) // 删掉多余的forceCenter配置 .force('x', d3.forceX(d => d.x).strength(1)) // 加大x方向力的强度,对齐更紧 .force('y', d3.forceY(height/2).strength(0.1)) // y方向统一以垂直中心为目标,允许散开 .force('collide', d3.forceCollide().radius(d => d.radius + 1)) // 加1px padding避免点边缘重叠 .stop(); force.tick(NUM_ITERATIONS); // 完全没用的tick函数可以直接删除,模拟结束后直接用d.x d.y绘制即可
内容的提问来源于stack exchange,提问作者Pdeuxa
相关产品推荐
相关产品推荐

