zoukankan      html  css  js  c++  java
  • 原创

    react + d3.js + TS 日轮图 类型优化

    1. 结构

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

    2. 类型优化

    2.1 d3.partiion<>()

    let root: d3.HierarchyRectangularNode<IDatum> = d3.partition<IDatum>().size([ 2 * Math.PI, height / 1.6  ])(
        d3
            .hierarchy<IDatum>(data)
            .sum((d: IDatum) => d.popularity || 0)
            .sort(
                (a: d3.HierarchyNode<IDatum>, b: d3.HierarchyNode<IDatum>) => (b.daa.popularity || 0) - (a.data.popularity || 0)
            )
    )
    

    2.2 d3.arc<>()

    const arc = d3
        .arc<d3.HierarchyRectangularNode<IDatum>>()
        .innerRadius((d: d3.HierarchyRectangularNode<IDatum>) => d.y0)
        .outerRadius((d: d3.HierarchyRectangularNode<IDatum>) => d.y1)
        .startAngle((d: d3.HierarchyRectanguleNode<IDatum>) => d.x0)
        .endAngle((d: d3.HierarchyRectanggularNode<IDatum>)=> d.x1)
        .padRadius(Math.PI / 2)
        .padRadius((d: d3.HierarchyNode<IDatum>) =>
            Math.min((d.x1 - d.x0) / 2, 0.005)    
        )
    

    2.3 selection.attr()

    g.selectAll('.datatext')
        .data(root.descendants().filter((d: any) => d.depth !== 0))
        .join("text")
        .attr("class", "datatext")
        .attr("text-anchor", "middle")
        .attr("pointer-events", "none")
        .attr("font-size", (d: d3.HierarchyRectangularNode<IDatum>) => d.data.name.length < 15 ? "1em" : ".85em")
        .attr("transform", (d: d3.HierarchyRectangularNode<IDatum>)=>{
            const x = (((d.x0 + d.x1) / 2) * 180 ) / Math.PI;
            const y = (d.y0 + d.y1) / 2;
            
            return `rotate(${x - 90} translate(${y}, 0)) rotate(${ x < 180 ? 0 : 180}) translate(0, 5)`;
        })
        .text((d: d3.HierarchyRectangularNode<IDatum>) => d.data.name);
    

    3. 代码

    
    import React, { useState, useRef, useEffect } from "react";
    import * as d3 from "d3";
    interface IGamesDatum {
      name: string;
      popularity: number;
    }
    interface IDatum {
      name: string;
      popularity?: number;
      children?: this[];
    }
    const SunBurst: React.FC = () => {
      const [width] = useState(1600);
      const [height] = useState(940);
      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.HierarchyRectangularNode<IDatum>;
        const svgSelection = d3.select(svg.current);
        svgSelection.attr("width", width).attr("height", height);
        const g = svgSelection
          .append("g")
          .attr("transform", `translate(${width / 2}, ${height / 2})`);
        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 arc = d3
          .arc<d3.HierarchyRectangularNode<IDatum>>()
          //   .innerRadius((d: any) => {
          //     return d.y0;
          //   })
          .innerRadius((d: d3.HierarchyRectangularNode<IDatum>) => d.y0)
          .outerRadius((d: d3.HierarchyRectangularNode<IDatum>) => d.y1)
          .startAngle((d: d3.HierarchyRectangularNode<IDatum>) => d.x0)
          .endAngle((d: d3.HierarchyRectangularNode<IDatum>) => d.x1)
          .padRadius(Math.PI / 2)
          .padAngle((d: d3.HierarchyRectangularNode<IDatum>) =>
            Math.min((d.x1 - d.x0) / 2, 0.005)
          );
        const render = (data: any) => {
          color = d3.scaleOrdinal(d3.schemeCategory10);
          g.selectAll(".datapath")
            .data<d3.HierarchyRectangularNode<IDatum>>(
              data.descendants().filter((d: any) => d.depth !== 0)
            )
            .join("path")
            .attr("class", "datapath")
            .attr("fill", fill)
            .attr("d", arc);
          g.selectAll(".datatext")
            .data(root.descendants().filter((d: any) => d.depth !== 0))
            .join("text")
            .attr("class", "datatext")
            .attr("text-anchor", "middle")
            .attr("pointer-events", "none")
            .attr("font-size", (d: d3.HierarchyRectangularNode<IDatum>) =>
              d.data.name.length < 15 ? "1em" : ".85em"
            )
            .attr("transform", (d: d3.HierarchyRectangularNode<IDatum>) => {
              const x = (((d.x0 + d.x1) / 2) * 180) / Math.PI;
              const y = (d.y0 + d.y1) / 2;
              //
              return `rotate(${x - 90}) translate(${y}, 0) rotate(${
                x < 180 ? 0 : 180
              }) translate(0, 5)`;
            })
            .text((d: d3.HierarchyRectangularNode<IDatum>) => d.data.name);
        };
        d3.json("./data/games.json").then((data: any) => {
          root = d3.partition<IDatum>().size([2 * Math.PI, height / 1.6])(
            d3
              .hierarchy<IDatum>(data)
              .sum((d: IDatum) => d.popularity || 0)
              .sort(
                (a: d3.HierarchyNode<IDatum>, b: d3.HierarchyNode<IDatum>) =>
                  (b.data.popularity || 0) - (a.data.popularity || 0)
              )
          );
          render(root);
        });
      });
      return (
        <>
          <svg ref={svg}></svg>
        </>
      );
    };
    export { SunBurst };
    
    
    

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

  • 相关阅读:
    unity_动画_状态机
    有内涵的技术论坛
    ios开发——常用经典算法OC篇&冒泡/快速
    iOS开发——C篇&文件操作
    iOS开发——C篇&预处理
    iOS开发——C篇&结构体与枚举
    iOS开发——C篇&函数解析
    iOS开发——C篇&动态内存分析
    UML第二次作业(代码互评)
    我与UML相爱相杀的狗血日常
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13772942.html
Copyright © 2011-2022 走看看