sector.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import { CompoundedComponent } from "@/types";
  2. import { register } from "@antv/x6-react-shape";
  3. import { Graph, Node } from "@antv/x6";
  4. import { ports, defaultData } from "../../config/data";
  5. import CustomInput from "../CustomInput";
  6. import { useSizeHook, useShapeProps } from "@/hooks";
  7. const component = ({ node }: { node: Node }) => {
  8. const { label, text, fill, stroke, opacity } = node.getData();
  9. const { size, ref } = useSizeHook();
  10. const {
  11. fillContent,
  12. defsContent,
  13. strokeColor,
  14. strokeWidth,
  15. strokeDasharray,
  16. } = useShapeProps(fill, size, stroke);
  17. const generatePath = (width: number, height: number, strokeWidth: number) => {
  18. let path = "";
  19. // 开始位置
  20. path += `M${width / 2} ${height - strokeWidth}`;
  21. path += `L${width - strokeWidth} ${height * 0.3}`;
  22. path += `C${width - strokeWidth},${height * 0.3} ${(width * 3) / 4},${strokeWidth} ${width / 2},${strokeWidth}`;
  23. path += `S${strokeWidth},${height * 0.3} ${strokeWidth},${height * 0.3}`;
  24. path += `L${width / 2} ${height - strokeWidth} Z`;
  25. return path;
  26. };
  27. return (
  28. <>
  29. <div
  30. className="relative text-0 w-full h-full"
  31. ref={ref}
  32. style={{ opacity: opacity / 100 }}
  33. >
  34. <CustomInput value={label} styles={text} node={node} />
  35. <svg
  36. className="w-full h-full"
  37. viewBox={`0 0 ${size?.width} ${size?.height}`}
  38. xmlns="http://www.w3.org/2000/svg"
  39. >
  40. <defs>{defsContent}</defs>
  41. <path
  42. d={generatePath(size?.width, size?.height, strokeWidth)}
  43. fill={fillContent}
  44. stroke={strokeColor}
  45. strokeDasharray={strokeDasharray}
  46. strokeWidth={strokeWidth}
  47. />
  48. </svg>
  49. </div>
  50. </>
  51. );
  52. };
  53. register({
  54. shape: "custom-react-sector",
  55. width: 80,
  56. height: 70,
  57. effect: ["data"],
  58. component: component,
  59. });
  60. // 左侧连接桩
  61. Graph.registerPortLayout("sectorLeft", (portsPositionArgs, elemBBox) => {
  62. return portsPositionArgs.map((item) => {
  63. return {
  64. ...item,
  65. position: {
  66. x: elemBBox.width / 4,
  67. y: elemBBox.height / 2,
  68. },
  69. };
  70. });
  71. });
  72. // 右侧连接桩
  73. Graph.registerPortLayout("sectorRight", (portsPositionArgs, elemBBox) => {
  74. return portsPositionArgs.map((item) => {
  75. return {
  76. ...item,
  77. position: {
  78. x: elemBBox.width * (3 / 4),
  79. y: elemBBox.height / 2,
  80. },
  81. };
  82. });
  83. });
  84. const Sector: CompoundedComponent = {
  85. name: "扇形",
  86. icon: require("./image/sector.png"),
  87. node: {
  88. shape: "custom-react-sector",
  89. data: {
  90. label: "",
  91. ...defaultData,
  92. },
  93. ports: {
  94. ...ports,
  95. groups: {
  96. ...ports.groups,
  97. sectorLeft: {
  98. position: "sectorLeft",
  99. attrs: {
  100. circle: {
  101. r: 4,
  102. magnet: true,
  103. stroke: "#5F95FF",
  104. strokeWidth: 1,
  105. fill: "#fff",
  106. style: {
  107. visibility: "hidden",
  108. },
  109. },
  110. },
  111. },
  112. sectorRight: {
  113. position: "sectorRight",
  114. attrs: {
  115. circle: {
  116. r: 4,
  117. magnet: true,
  118. stroke: "#5F95FF",
  119. strokeWidth: 1,
  120. fill: "#fff",
  121. style: {
  122. visibility: "hidden",
  123. },
  124. },
  125. },
  126. },
  127. },
  128. items: [
  129. {
  130. group: "top",
  131. args: {
  132. dy: 2,
  133. },
  134. },
  135. {
  136. group: "sectorRight",
  137. },
  138. {
  139. group: "bottom",
  140. args: {
  141. dy: -2,
  142. },
  143. },
  144. {
  145. group: "sectorLeft",
  146. },
  147. ],
  148. },
  149. },
  150. };
  151. export default Sector;