reactjs – 使用d3-hierarchy和动画在树根周围分布节点

我有附加的 a code sandbox显示我的解决方案.

我觉得我的解决方案不正确,因为我在NodesFanout组件中完成了所有计算.

import * as React from "react";
import NodeGroup from "react-move/NodeGroup";
import { StructureItem } from "../../types";
import { Node } from "../Node";
import { HierarchyPointNode } from "d3-hierarchy";
import { HierarchyLabelProps } from "../HierarchyLabel";
import { findindex } from "lodash";
import { NodeHeight } from "../Tree";
import { findCollapsedParent } from "../../util/node";

const { Group } = require("@vx/group");

export interface NodesProps {
  nodes: HierarchyPointNode<StructureItem>[];
  clickHandler: any;
  shapeLength: number;
  collapse: boolean;
  Label: React.ComponentType<HierarchyLabelProps>;
  LabelCollapsed: React.ComponentType<HierarchyLabelProps>;
}

const positionNodes = (
  node: HierarchyPointNode<StructureItem>,nodes: HierarchyPointNode<StructureItem>[]
) => {
  let left: number;
  let top: number;

  if (!node.parent) {
    left = node.y / 2 - NodeHeight;
    top = node.x - NodeHeight;
  } else if (node.data && node.data.isRight) {
    const index = findindex(nodes,node);
    const lastLeft = nodes[index - 1];

    top = lastLeft.x;
    left = NodeHeight;
  } else {
    top = node.x;
    left = node.y;
  }

  return {
    top: [top],left: [left],opacity: [1]
  };
};

export const NodesFanout: React.SFC<NodesProps> = ({
  Label,LabelCollapsed,nodes,shapeLength,clickHandler,collapse
}) => {
  return (
    <NodeGroup
      data={nodes}
      keyAccessor={(d: HierarchyPointNode<StructureItem>) => d.data.id}
      start={(node: HierarchyPointNode<StructureItem>) => {
        let left: number;
        let top: number;

        if (!node.parent) {
          left = node.y / 2 - NodeHeight;
          top = node.x - NodeHeight;
        } else {
          left = node.parent.y / 2;
          top = node.parent.x;
        }

        return {
          top,left,opacity: 0
        };
      }}
      enter={node => positionNodes(node,nodes)}
      update={node => positionNodes(node,nodes)}
      leave={node => {
        let left: number;
        let top: number;

        const collapsedParent = findCollapsedParent(
          node.parent
        ) as HierarchyPointNode<StructureItem>;

        if (!collapsedParent.parent) {
          left = collapsedParent.y / 2;
          top = collapsedParent.x - NodeHeight;
        } else {
          left = collapsedParent.parent.y / 2;
          top = collapsedParent.parent.x - NodeHeight;
        }

        return {
          top: [top],opacity: [0]
        };
      }}
    >
      {nodes => (
        <Group>
          {nodes.map(({ key,data: node,state },index) => {
            return (
              <Group
                top={state.top}
                left={state.left}
                key={key}
                opacity={state.opacity}
                className={`node__${index}`}
              >
                <Node
                  Label={Label}
                  LabelCollapsed={LabelCollapsed}
                  node={node}
                  shapeLength={shapeLength}
                  clickHandler={(e: any) => {
                    clickHandler({ e,node });
                  }}
                  key={key}
                  collapse={collapse}
                />
              </Group>
            );
          })}
        </Group>
      )}
    </NodeGroup>
  );
};

动画也没有正确地从中心散开.

我试图实现像this这样的所有节点从中心扩散出来的东西.

有更好的方法吗?

解决方法

我相信这实现了目标: https://codesandbox.io/s/w4n1v3xvw

我不认为代码是有问题的,它只是你所基于的例子是片面的,所以离开动画需要根据每个节点的一面进行更新.

这是在更改之前更改了注释的代码

leave={node => {
        let left: number;
        let top: number;
        let nodeIndex: number;

        const collapsedParent = findCollapsedParent(
          node.parent
        ) as HierarchyPointNode<StructureItem>;

        if (!collapsedParent.parent) {
          // Get this nodes index from its' position in the parent
          nodeIndex = findindex(node.parent.children,node);

          // Even indices go one side and odd go to the other
          // So we add a modifier which changes sign based on NodeHeight
          let modifier: number = NodeHeight;
          if (nodeIndex % 2 == 1) {
            modifier *= -1;
          }

          // We add the modifier in the left calculation
          left = collapsedParent.y / 2 + modifier;
          top = collapsedParent.x - NodeHeight;
        } else {
          left = collapsedParent.parent.y / 2;
          top = collapsedParent.parent.x - NodeHeight;
        }

        return {
          top: [top],opacity: [0]
        };
      }}

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...