• 原创- react + d3.js +TS 实现冰柱图 类型优化


    react + d3.js + TS 实现冰柱图

    1. 结构

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

    2.1 类型优化

    2.1.1 d3.partition<>()()

    d3.json<IDatum>("./data/games.json").then(data: IDatum | undefined) => {
        let root: d3.HierarchyRectangularNode<IDatum> =  d3.partition<IDatum>.size([height, width])(
                        d3.hierarchy<IDatum>(data, (d:IDatum) => d.children? d.children : null)
                        .sum((d: IDatum) => (d.popularity ? d.popularity : 0))
                        .sort(
                            (a: d3.HierarchyNode<IDatum>, b: d3.HierarchyNode<IDatum>) =>
                                (b.data.popularity || 0) - (a.data.popularity || 0)
                        )
    )
    
    });
    
    

    2.1.2 .attr('x', valueFun)

    g.selectAll(".datarect")
        .data(root.descendants())
        .join("rect")
        .attr("class", "datarect")
        .attr("x", (d: d3.HierarRectangularNode<IDatum>) => d.yo / 2)
        .attr("y", (d: d3.HierarRectangularNode<IDatum>) => d.x0 / 2)
        .attr("height", (d: d3.HierarRectangularNode<IDatum>) => (d.x1 - d.x0) / 4)
        .attr("width", (d: d3.HierarchyRectangularNode<IDatum>) => (d.y1 - d.yo) / 2)
        .attr("fill", fill)
    

    3 代码

    import React, { useState, useRef, useEffect } from "react";
    import * as d3 from "d3";
    import { HierarchyNode } from "d3";
    import { isDate } from "moment";
    interface IGamesDatum {
      name: string;
      popularity: number;
    }
    interface IDatum {
      name: string;
      children?: this[];
      popularity?: number;
    }
    interface IDatumSum {
      name: string;
      children: this | IGamesDatum[];
      popularity: number;
    }
    const Icicle: React.FC = () => {
      const [width] = useState(1400);
      const [height] = useState(7000);
      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(${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: d3.HierarchyRectangularNode<IDatum>) => {
          color = d3.scaleOrdinal(d3.schemeCategory10);
          g.selectAll(".datarect")
            .data(root.descendants())
            .join("rect")
            .attr("class", "datarect")
            .attr("x", (d: d3.HierarchyRectangularNode<IDatum>) => d.y0 / 2)
            .attr("y", (d: d3.HierarchyRectangularNode<IDatum>) => d.x0 / 4)
            .attr(
              "height",
              (d: d3.HierarchyRectangularNode<IDatum>) => (d.x1 - d.x0) / 4
            )
            .attr(
              "width",
              (d: d3.HierarchyRectangularNode<IDatum>) => (d.y1 - d.y0) / 2
            )
            .attr("fill", fill);
          g.selectAll(".datatext")
            .data(
              root
                .descendants()
                .filter(
                  (d: d3.HierarchyRectangularNode<IDatum>) => d.x1 - d.x0 > 50
                )
            )
            .join("text")
            .attr("class", "datatext")
            .attr("text-anchor", "middle")
            .attr(
              "x",
              (d: d3.HierarchyRectangularNode<IDatum>) => (d.y0 + d.y1) / 4
            )
            .attr(
              "y",
              (d: d3.HierarchyRectangularNode<IDatum>) => (d.x0 + d.x1) / 8
            )
            .attr("dy", "0.35em")
            .attr("font-size", "1em")
            .text((d: d3.HierarchyRectangularNode<IDatum>) => d.data.name);
        };
        d3.json<IDatum>("./data/games.json").then((data: IDatum | undefined) => {
          if (data) {
            root = d3.partition<IDatum>().size([height, width])(
              d3
                .hierarchy<IDatum>(data, (d: IDatum) =>
                  d.children ? d.children : null
                )
                .sum((d: IDatum) => (d.popularity ? 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 { Icicle };
    

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

  • 相关阅读:
    SIMPLE QUERY几个原则
    [POI2014]DOO-Around the world
    Java 实现 蓝桥杯 历届试题 分糖果
    or小计
    luoguP1357 花园
    like小计
    [NOI2016]区间
    complex query几个原则
    AGC 018E.Sightseeing Plan——网格路径问题观止
    排查一般MySQL性能问题
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13772825.html
Copyright © 2020-2023  润新知