• 原创


    react + d3.js + ts 实现树图 报错解决

    1. 结构

    interface IGamesDatum {
        name: string;
        popularity: number;
    }
    
    interface IDatum {
        name: string;
        children: this | IGamesDatum[];
    }
    

    2. 类型优化

    2.1 d3.hierarchy()

    d3.json<IDatum>("./data/games.json").then((data: IDatum | undefined) => {
        if(data){
            let dataHierarchyNode: d3.HierarchyNode<IDatum> = d3.hierarchy<IDatum>(data);
        }
    });
    

    根据指定的层级数据创建一个根节点,类型为 HierarchyNode

    2.2 d3.tree()

    let root: d3.HierarchyPointNode<IDatum> = d3.tree<IDatum>().size([innerHeight, innerWidth])(dataHierarchyNode);
    

    2.3 d3.linkHorizontal<>()

    g.selectAll("path")
        .data(root.links())
        .attr("d", d3.linkHorizontal<d3.HierarchyPointLink<IDatum>, d3.HierarchyPointNode<IDatum>>()
        .x((d: d3.HierarchyPointNode<IDatum>) => d.y)
        .y((d: d3.HierarchyPointNode<IDatum>) => d.x))
    

    3. 代码

    
    import React, { useState, useRef, useEffect } from "react";
    import * as d3 from "d3";
    interface IGamesDatum {
      name: string;
      popularity: number;
    }
    interface IDatum {
      name: string;
      children: this | IGamesDatum[];
    }
    const Tree: React.FC = () => {
      const [width] = useState(1600);
      const [height] = useState(800);
      const [margin] = useState({
        left: 150,
        top: 60,
        right: 50,
        bottom: 50,
      });
      const innerWidth = width - margin.left - margin.right;
      const innerHeight = height - margin.top - margin.bottom;
      const svg = useRef<SVGSVGElement>(null);
      useEffect(() => {
        let root: d3.HierarchyPointNode<IDatum>;
        const svgSelection = d3.select(svg.current);
        svgSelection.attr("width", width).attr("height", height);
        const g = svgSelection
          .append("g")
          .attr("transform", `translate(${margin.left}, ${margin.right})`);
        let color: any;
        const fill = (d: any) => {
          if (d.depth === 0) return color(d.data.name);
          while (d.depth > 1) d = d.parent;
          return color(d.data.name);
        };
        const render = (data: any) => {
          color = d3.scaleOrdinal(d3.schemeCategory10);
          // .domain(
          //   root
          //     .descendants()
          //     .filter((d) => d.depth <= 1)
          //     .map((d) => d.data.name)
          // )
          // .range(d3.schemeCategory10);
          g.selectAll("path")
            .data(root.links())
            .join("path")
            .attr("fill", "none")
            .attr("stroke", "black")
            .attr("stroke-width", 1.5)
            .attr(
              "d",
              d3
                .linkHorizontal<
                  d3.HierarchyPointLink<IDatum>,
                  d3.HierarchyPointNode<IDatum>
                >()
                .x((d: d3.HierarchyPointNode<IDatum>) => d.y)
                .y((d: d3.HierarchyPointNode<IDatum>) => d.x)
            )
            .text("1");
          g.selectAll("circle")
            .data(root.descendants())
            .join("circle")
            .attr("cx", (d: any) => d.y)
            .attr("cy", (d: any) => d.x)
            .attr("fill", fill)
            .attr("stroke-width", 3)
            .attr("r", 6);
          g.selectAll("text")
            .data(root.descendants())
            .join("text")
            .attr("text-anchor", (d) => (d.children ? "end" : "start"))
            // note that if d is a child, d.children is undefined which is actually false!
            .attr("x", (d: any) => (d.children ? -6 : 6) + d.y)
            .attr("y", (d: any) => d.x + 5)
            .text((d) => d.data.name);
        };
        d3.json<IDatum>("./data/games.json").then((data: IDatum | undefined) => {
          if (data) {
            let dataHierarchyNode: d3.HierarchyNode<IDatum> = d3.hierarchy<IDatum>(
              data
            );
            root = d3.tree<IDatum>().size([innerHeight, innerWidth])(
              dataHierarchyNode
            );
            render(root);
          }
        });
      });
      return (
        <>
          <svg ref={svg}></svg>
        </>
      );
    };
    export { Tree };
    
    
    

    原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13771633.html
    GitHub: https://github.com/lemon-Xu/Learning-d3.-Js
    作者: lemon

  • 相关阅读:
    执行分布式检索
    Nginx 配置文件介绍
    Nginx反向代理实例
    ElasticSearch相关概念(术语)
    后置过滤Post filter
    资深产品经理都在用哪些工具
    项目管理的基本流程
    中小企业都在用哪些Wiki网站?11款Wiki网站盘点
    做好项目实施计划的4大要素集常用工具
    2022年5大最佳软件bug管理系统盘点
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13771633.html
Copyright © 2020-2023  润新知