123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- import { register } from "@antv/x6-react-shape";
- import { EventArgs, Graph, Node, Path } from "@antv/x6";
- import { topicData } from "@/config/data";
- import { useSizeHook, useShapeProps } from "@/hooks";
- import CustomInput from "../CustomInput";
- import { useEffect, useState } from "react";
- import { PlusOutlined } from "@ant-design/icons";
- import { TopicType } from "@/enum";
- import { addTopic } from "@/utils/mindMap";
- const component = ({ node, graph }: { node: Node; graph: Graph }) => {
- const { fill, stroke, opacity, label, text, borderSize } = node.getData();
- const { size, ref } = useSizeHook();
- const { fillContent, strokeColor, strokeWidth, strokeDasharray } =
- useShapeProps(fill, size, stroke);
- const [selected, setSelected] = useState(true);
- const handleSelect = (_args: EventArgs["node:selected"]) => {
- const cells = graph.getSelectedCells();
- setSelected(cells.length === 1 && cells[0].id === node.id);
- };
- useEffect(() => {
- graph.createTransformWidget(node);
- graph.select(node);
- graph.on("node:selected", handleSelect);
- graph.on("node:unselected", handleSelect);
- return () => {
- graph.off("node:selected", handleSelect);
- graph.off("node:unselected", handleSelect);
- };
- }, []);
- const handleAddBranch = () => {
- const data = node.getData();
- if( data.type === TopicType.main) {
- addTopic(node, TopicType.branch);
- } else {
- addTopic(node, TopicType.sub);
- }
- }
-
- return (
- <>
- <div
- className="relative text-0 w-full h-full"
- ref={ref}
- style={{
- opacity: opacity / 100,
- border: `solid ${strokeWidth}px ${strokeColor}`,
- background: fillContent,
- borderRadius: borderSize,
- }}
- >
- <CustomInput value={label} node={node} styles={text} />
- {selected && (
- <div
- className={`
- absolute
- w-20px
- h-20px
- rounded-full
- right--25px
- top-50%
- translate-y-[-50%]
- flex
- justify-center
- items-center
- text-12px
- cursor-pointer
- bg-#eef0f3
- color-#9aa5b8
- hover:bg-#067bef
- hover:color-white`}
- onClick={handleAddBranch}
- >
- <PlusOutlined />
- </div>
- )}
- </div>
- </>
- );
- };
- // 连接器
- Graph.registerConnector(
- "mindmap",
- (sourcePoint, targetPoint, routerPoints, options) => {
- const midX = sourcePoint.x + 10;
- const midY = sourcePoint.y;
- const ctrX = (targetPoint.x - midX) / 5 + midX;
- const ctrY = targetPoint.y;
- const pathData = `
- M ${sourcePoint.x} ${sourcePoint.y}
- L ${midX} ${midY}
- Q ${ctrX} ${ctrY} ${targetPoint.x} ${targetPoint.y}
- `;
- return options.raw ? Path.parse(pathData) : pathData;
- },
- true
- );
- // 注册思维导图边
- Graph.registerEdge(
- "mindmap-edge",
- {
- inherit: "edge",
- connector: {
- name: "mindmap",
- },
- attrs: {
- line: {
- targetMarker: "",
- stroke: "#A2B1C3",
- strokeWidth: 2,
- },
- },
- zIndex: 0,
- },
- true
- );
- // 主题
- register({
- shape: "mind-map-topic",
- width: 206,
- height: 70,
- effect: ["data"],
- component: component,
- });
- const baseNode = {
- shape: "mind-map-topic",
- data: {
- label: "",
- ...topicData,
- },
- };
- export default baseNode;
|