D3ForceLayout: 配置的 center / centerX / x / y / radial 坐标及 radius 参数被默认值覆盖失效
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 75/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- d3, typescript
- Área
- data-visualization
Línea de trabajo
El problema del orden de fusión está en src/algorithm/d3-force/index.ts, en getCenterOptions, getXForceOptions, getYForceOptions y getRadialOptions, donde los valores por defecto se aplican después de las opciones del usuario mediante assignDefined. Empieza ejecutando el script de reproducción del issue para confirmar que el centroide es [350, 350] y que el valor de radial.radius es 100. Se considera terminado cuando se respetan los valores center, centerX/centerY, las coordenadas x/y/radial del force y radial.radius proporcionados por el usuario, y los layouts sin configurar siguen igual.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
版本
@antv/layout:2.0.1(npmbeta),v5分支(62bb479)同样可复现- Node.js: 24
问题描述
D3ForceLayout 在合并配置时,默认值后置覆盖了用户传入的参数,导致以下自定义配置失效:
- 中心点配置失效:
center: { x, y }与文档推荐的快捷字段centerX/centerY均不生效,中心点始终固定为视口中心[width / 2, height / 2](且源码中未读取centerX/centerY)。 - 力的坐标被覆盖:中心力开启时(默认开启),
x: { x }、y: { y }、radial: { x, y }均会被中心点坐标覆盖。 - 径向半径被覆盖:
radial: { radius }始终被默认值100覆盖。
复现
const { D3ForceLayout } = require('@antv/layout');
const data = {
nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }, { id: 'd' }],
edges: [
{ id: 'e1', source: 'a', target: 'b' },
{ id: 'e2', source: 'b', target: 'c' },
{ id: 'e3', source: 'c', target: 'd' },
],
};
const centroid = async (options) => {
const layout = new D3ForceLayout({ width: 700, height: 700, ...options });
await layout.execute(data);
let x = 0, y = 0, n = 0;
layout.forEachNode((node) => { x += node.x; y += node.y; n += 1; });
return [Math.round(x / n), Math.round(y / n)];
};
(async () => {
console.log(await centroid({ center: { x: 300, y: 200 } })); // 实际: [350, 350], 期望: [300, 200]
console.log(await centroid({ centerX: 300, centerY: 200 })); // 实际: [350, 350], 期望: [300, 200]
const layout = new D3ForceLayout({
width: 700,
height: 700,
x: { x: 100 },
radial: { x: 100, y: 100, radius: 50 },
});
await layout.execute(data);
console.log(layout.getForce('x').x()()); // 实际: 350, 期望: 100
console.log(layout.getForce('radial').x(), layout.getForce('radial').y()); // 实际: 350 350, 期望: 100 100
console.log(layout.getForce('radial').radius()()); // 实际: 100, 期望: 50
})();
问题原因
在 src/algorithm/d3-force/index.ts 中,getCenterOptions、getXForceOptions、getYForceOptions 和 getRadialOptions 合并配置时使用了如下写法:
return assignDefined({}, options.center || {}, {
x: viewport.width / 2,
y: viewport.height / 2,
strength: options.centerStrength,
});
默认值对象放在了用户配置对象之后,直接覆盖了用户传入的自定义值(如视口中心 width / 2、中心点坐标、radius: 100)。
修复建议
将默认值前置,调整合并顺序为:默认值 → force 对象 → 快捷字段。
这样仅在未配置时使用默认值,未配置相关参数的已有布局不受影响。我稍后会提交对应的修复 PR。
待确认问题
- 配置优先级:文档
d3-force-options说明为“两者混用时以 force 对象为准”,但当前代码实现中所有 getter(如manyBody与nodeStrength、center.strength与centerStrength)均为“快捷字段优先覆盖 force 对象”。PR 沿用了现有实现的约定,是否需要后续统一调整文档或实现? - 中心配置文档说明:同一文档的“通用配置”中提到“
D3ForceLayout中心相关配置不使用center,而是使用centerX/centerY”,但在“2D 扩展”章节和 TypeScript 类型定义中均支持center: false | { x?, y?, strength? }。该处文档说明是否需要同步修正?
- Lenguaje dominante
- TypeScript
- Estrellas
- 280
- Forks
- 61
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de antvis/layout
-
Dificultad 3/5 Medio día Aptitud para principiantes 35/100
-
ComboCombinedLayout 子节点未生成位置信息Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
-
layout-gpu
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
Todos los issues de antvis/layout
Issues similares
-
mobile-app
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
Open-Locker/Open-Locker#352 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
leanprover-community/lean4game#589 ·
Los mantenedores suelen responder en 2 días
-
Add: CS Action BGAbiertocheck:passed streams:add
Dificultad 1/5 Menos de una hora Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
unocss/unocss#5421 · 1 comentario ·
Los mantenedores suelen responder en 1 día