我随附了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],
left: [left],
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之类的东西,其中所有节点都从中心散开。
有更好的方法吗?
答案 0 :(得分:6)
我相信这可以达到目标:https://codesandbox.io/s/w4n1v3xvw
我认为代码没有问题,您所基于的示例只是一个例子,因此leave
动画需要根据每个节点的侧面进行更新。
这是更改前带有注释的代码:
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],
left: [left],
opacity: [0]
};
}}