我正在尝试在 React 组件中创建一个径向树,如下所示:https://observablehq.com/@d3/radial-tree/2
(除了我不想要文本标签,我想要节点)
我的数据如下:
[{
id: 1,
parentId: null,
title: “rootnode”},
{
id: 2,
parentId: 1,
title: “child1"
},
{
id: 3,
parentId: 1,
title: “child2”},
etc
]
我还可以使用 Sequelize 查询包含任何数据点子级的数组
但无论我怎么尝试,似乎数据都没有按分层方式读取?
.stratify() 函数抛出“分层上没有根节点”
错误
.hierarchy(data) 函数不会抛出任何错误,但页面上不会出现任何内容。
我认为问题是我的数据设置不正确,但我尝试了很多变体但没有任何效果。
现在,当我 console.log 根(在绘图函数中)时,它会打印一个“节点”元素,该元素似乎将我的所有数据作为参数。
我的树组件如下所示:
import { useState, useEffect, useRef } from "react";
import * as d3 from "d3";
export default function Tree({ data }) {
const svgRef = useRef();
useEffect(() => {
const tree = d3.cluster()
.size([2 * Math.PI, Math.min(928, 928) / 2 - 30])
.separation((a, b) => (a.parent === b.parent ? 1 : 2) / a.depth);
const root = d3.hierarchy(data)
draw(tree(root));
}, [data]);
function draw(root) {
console.log(root)
const svg = d3.select(svgRef.current)
console.log(svg)
svg.append("g")
.attr("fill", "none")
.attr("stroke", "#555")
.attr("stroke-opacity", 0.4)
.attr("stroke-width", 1.5)
.selectAll()
.data(root.links())
.join("path")
.attr("d", d3.linkRadial()
.angle(d => d.x)
.radius(d => d.y));
svg.append("g")
.selectAll()
.data(root.descendants())
.join("circle")
// .attr("transform", d => `rotate(${d.x * 180 / Math.PI - 90}) translate(${d.y},0)`)
.attr("fill", d => d.children ? "#555" : "#999")
.attr("r", 2.5);
svg.append("g")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 3)
.selectAll()
.data(root.descendants())
return svg.node();
}
return (
<div>
<svg ref={svgRef} id="myTree" width="1000" height="1000"></svg>
</div>
);
}
谢谢!!!
为了使数据具有层次结构,它需要是一个代表根节点的对象,并且需要有一个 children 属性,其中包含所有根节点子节点的数组。这些孩子可以包含更多的孩子。
D3 文档中的示例 (https://d3js.org/d3-hierarchy/hierarchy):
const data = {
name: "Eve",
children: [
{name: "Cain"},
{name: "Seth", children: [{name: "Enos"}, {name: "Noam"}]},
{name: "Abel"},
{name: "Awan", children: [{name: "Enoch"}]},
{name: "Azura"}
]
};
因此,为了使上述数据具有层次结构,应采用以下格式:
{
name: “rootnode”,
id: 1,
parentId: null,
children: [
{name: “child1“,
id: 2,
parentId: 1},
{name: “child2”
id: 3,
parentId: 1}
]
}