D3树状图部分链接线条过粗问题求助
D3.js树状图部分链接过粗问题排查
我用D3.js绘制树状图时,发现部分链接路径比其他链接粗很多,想把这些过粗的路径调整成和垂直路径一致的粗细。查了很多树状图示例,链接线条都是统一粗细,麻烦帮忙排查原因。
Tree 代码
const stratifier = stratify<Leaf>() .id((d) => d.name) .parentId((d) => d.parentName) const root = useMemo(() => { if (loading) return null if (error) return null if (data?.leaves.length === 0 || data === undefined) return null const leaves = data?.leaves.map((leaf) => ({ name: leaf.name, description: leaf.description, parentName: leaf.parentName ?? '', children: leaf.children?.map((leaf) => ({ name: leaf?.name ?? '', })) ?? [], })) ?? [] return stratifier(leaves) }, [data, stratifier, loading, error]) const setupTree = useMemo(() => { if (!root) return const result = tree<Leaf>().size([500, 500])(root) return result }, [root]) const links = useMemo(() => setupTree?.links(), [setupTree]) const convertLink = useCallback( (link: HierarchyPointLink<Leaf>): DefaultLinkObject => ({ source: [link.source.x, link.source.y], target: [link.target.x, link.target.y], }), [])
JSX 路径代码
{links?.map((link, i) => { const convertedLink = convertLink(link) return ( <path key={`${i}-link`} d={linkVertical() .source((d) => d.target) .target((d) => d.source)(convertedLink) ?? '' } stroke="black" strokeWidth="2" style={{ transform: `translate(${margin}px, ${margin}px)` }} /> ) })}
分层数据
{ "data": { "leaves": [ { "name": "A", "parentName": null, "description": "This is a description of A", "children": [ { "name": "B", "__typename": "Leaf" }, { "name": "C", "__typename": "Leaf" }, { "name": "D", "__typename": "Leaf" } ], "__typename": "Leaf" }, { "name": "B", "parentName": "A", "description": "This is a description of B", "children": [ { "name": "B-1", "__typename": "Leaf" }, { "name": "B-2", "__typename": "Leaf" }, { "name": "B-3", "__typename": "Leaf" } ], "__typename": "Leaf" }, { "name": "B-1", "parentName": "B", "description": "This is a description of B-1", "children": [], "__typename": "Leaf" }, { "name": "B-2", "parentName": "B", "description": "This is a description of B-2", "children": [], "__typename": "Leaf" }, { "name": "B-3", "parentName": "B", "description": "This is a description of B-3", "children": [], "__typename": "Leaf" }, { "name": "C", "parentName": "A", "description": "This is a description of C", "children": [], "__typename": "Leaf" }, { "name": "D", "parentName": "A", "description": "This is a description of D", "children": [], "__typename": "Leaf" } ] } }
问题根源与修复方案
核心问题
- 重复链接生成:你的分层数据中,父节点(如A)既作为独立条目存在,又在自身
children数组中列出子节点。stratifier处理时会基于parentId和children数组重复生成同一条链接,两条完全重叠的路径叠加后,视觉上就会显得更粗。 - 路径起点终点反转:调用
linkVertical()时,错误设置了.source((d) => d.target)和.target((d) => d.source),配合convertLink的正常映射,进一步加剧了路径重叠的问题。
修复步骤
1. 清理数据结构
stratifier只需要每个节点的name(id)和parentName就能构建树,不需要父节点中的children数组,删除该字段避免重复链接:
{ "data": { "leaves": [ { "name": "A", "parentName": null, "description": "This is a description of A", "__typename": "Leaf" }, { "name": "B", "parentName": "A", "description": "This is a description of B", "__typename": "Leaf" }, { "name": "B-1", "parentName": "B", "description": "This is a description of B-1", "__typename": "Leaf" }, { "name": "B-2", "parentName": "B", "description": "This is a description of B-2", "__typename": "Leaf" }, { "name": "B-3", "parentName": "B", "description": "This is a description of B-3", "__typename": "Leaf" }, { "name": "C", "parentName": "A", "description": "This is a description of C", "__typename": "Leaf" }, { "name": "D", "parentName": "A", "description": "This is a description of D", "__typename": "Leaf" } ] } }
2. 修正链接生成逻辑
去掉linkVertical()的反转设置,直接使用原始链接对象(无需额外转换):
{links?.map((link, i) => ( <path key={`${i}-link`} d={linkVertical()(link) ?? ''} stroke="black" strokeWidth="2" style={{ transform: `translate(${margin}px, ${margin}px)` }} /> ))}
如果确实需要保留转换逻辑,保持convertLink的正确性,不要反转source和target:
const convertLink = useCallback( (link: HierarchyPointLink<Leaf>): DefaultLinkObject => ({ source: [link.source.x, link.source.y], target: [link.target.x, link.target.y], }), [] )
d={linkVertical()(convertedLink) ?? ''}
完成修改后,每个节点间只会生成一条链接,所有线条粗细将保持一致。
内容的提问来源于stack exchange,提问作者Kraken
相关产品推荐
相关产品推荐

