使用D3渲染树,数据没有正确设置为层次结构?

问题描述 投票:0回答:1

我正在尝试在 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>
  );
}

谢谢!!!

reactjs svg d3.js tree
1个回答
0
投票

为了使数据具有层次结构,它需要是一个代表根节点的对象,并且需要有一个 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}
    ]
}
© www.soinside.com 2019 - 2024. All rights reserved.