Explorar o código

储存,回家研究

hbchen hai 1 ano
pai
achega
bdec38e376

+ 1 - 0
package.json

@@ -13,6 +13,7 @@
     "build.test": "node build/build.test.js"
   },
   "dependencies": {
+    "@antv/hierarchy": "^0.6.11",
     "@antv/x6": "^1.29.1",
     "@fullcalendar/interaction": "^5.10.1",
     "@fullcalendar/timegrid": "^5.10.1",

+ 138 - 311
src/views/sandbox_manage/common/edge.js

@@ -2,320 +2,147 @@ import { configOpt } from './toolConfig';
 
 const { line} = configOpt;
 
-//定义图形
-// const configStyles = {
-// 	rect: {
-// 		width: '60px',
-// 		height: '40px',
-// 		border: `1px solid ${border.borderColor}`,
-// 		backgroundColor: border.fill,
-// 	},
-// 	roundRect: {
-// 		width: '60px',
-// 		height: '40px',
-// 		border: `1px solid ${border.borderColor}`,
-// 		backgroundColor: border.fill,
-// 		borderRadius:"8px"
-// 	},
-// 	ellipse:{
-// 		width: '60px',
-// 		height: '40px',
-// 		border: `1px solid ${border.borderColor}`,
-// 		backgroundColor: border.fill,
-// 		borderRadius:"100%"
-// 	},
-// 	rhomboid:{
-// 		width: '50px',
-// 		height: '50px',
-// 		border: `1px solid ${border.borderColor}`,
-// 		backgroundColor: border.fill,
-// 		transform: 'rotate(-45deg) scale(0.7)'
-// 	},
-// 	text: {
-// 		width: '60px',
-// 		height: '40px',
-// 		textAlign: 'center',
-// 		lineHeight: '40px',
-// 		background: '#fff',
-// 		color: text.color,
-// 		fontSize: '14px',
-// 		fontWeight: 'normal',
-// 	},
-// }
-
 // export const myEdges = [
 // 	{
-// 		key: 'noArrowStraight',
+// 		type: 'noArrowStraight',
 //     ImgUrl:'~@/assets/icons/arrow.svg'
 // 	}
 // ]
-
-
-// /* ports 样式 */
-// export const portStyle = {
-// 	attrs: {
-// 		circle: {
-// 				// dataClass: 'choice-point',
-// 				r: 5,
-// 				magnet: true,
-// 				stroke: border.borderColor,
-// 				strokeWidth: 1,
-// 				fill: '#fff'
-// 		}
-// 	}
-// }
-// // 创建的节点配置 矩形、圆角矩形、椭圆形、菱形、文本
-// export const myNodeOption = (key) => {
-// 	switch (key) {
-// 		case 'rect': 
-// 			return {
-// 				width: 60,
-// 				height: 40,
-// 				data: {
-// 					key
-// 				},
-// 				attrs: {
-// 					rect: {
-// 						stroke: border.borderColor,
-// 						strokeWidth: border.width,
-// 						fill: border.fill,
-// 						strokeDasharray: null,
-// 					},
-// 					text: {
-// 						fill: text.color,
-// 						fontSize: text.size,
-// 						lineHeight: text.lineHeight,
-// 						fontWeight: 'normal',
-// 						textWrap: {
-// 							width: -10,
-// 						},
-// 					}
-// 				},
-// 				ports: {
-// 					items: [
-// 							{ group: 'port-top', id: 'p_top' },
-// 							{ group: 'port-bottom', id: 'p_bottom' },
-// 							{ group: 'port-left', id: 'p_left' },
-// 							{ group: 'port-right', id: 'p_right' },
-// 					],
-// 					groups: {
-// 							"port-top": {
-// 									position: 'top',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-bottom": {
-// 									position: 'bottom',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-left": {
-// 									position: 'left',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-right": {
-// 									position: 'right',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 					}
-// 				},
-// 			}
-// 		case 'roundRect': 
-// 			return {
-// 				width: 60,
-// 				height: 40,
-// 				data: {
-// 					key
-// 				},
-// 				attrs: {
-// 					rect: {
-// 						stroke: border.borderColor,
-// 						strokeWidth: border.width,
-// 						fill: border.fill,
-// 						strokeDasharray: null,
-// 						rx:8,
-// 						ry:8
-// 					},
-// 					text: {
-// 						fill: text.color,
-// 						fontSize: text.size,
-// 						lineHeight: text.lineHeight,
-// 						fontWeight: 'normal',
-// 						textWrap: {
-// 							width: -10,
-// 						},
-// 					}
-// 				},
-// 				ports: {
-// 					items: [
-// 							{ group: 'port-top', id: 'p_top' },
-// 							{ group: 'port-bottom', id: 'p_bottom' },
-// 							{ group: 'port-left', id: 'p_left' },
-// 							{ group: 'port-right', id: 'p_right' },
-// 					],
-// 					groups: {
-// 							"port-top": {
-// 									position: 'top',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-bottom": {
-// 									position: 'bottom',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-left": {
-// 									position: 'left',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-right": {
-// 									position: 'right',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 					}
-// 				},
-// 			}
-// 		case 'ellipse': 
-// 			return {
-// 				width: 60,
-// 				height: 40,
-// 				data: {
-// 					key
-// 				},
-// 				attrs: {
-// 					ellipse: {
-// 						stroke: border.borderColor,
-// 						strokeWidth: border.width,
-// 						fill: border.fill,
-// 						strokeDasharray: null,
-// 					},
-// 					text: {
-// 						fill: text.color,
-// 						fontSize: text.size,
-// 						lineHeight: text.lineHeight,
-// 						fontWeight: 'normal',
-// 						textWrap: {
-// 							width: -10,
-// 						},
-// 					}
-// 				},
-// 				ports: {
-// 					items: [
-// 							{ group: 'port-top', id: 'p_top' },
-// 							{ group: 'port-bottom', id: 'p_bottom' },
-// 							{ group: 'port-left', id: 'p_left' },
-// 							{ group: 'port-right', id: 'p_right' },
-// 					],
-// 					groups: {
-// 							"port-top": {
-// 									position: 'top',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-bottom": {
-// 									position: 'bottom',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-left": {
-// 									position: 'left',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-right": {
-// 									position: 'right',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 					}
-// 				},
-// 			}
-// 		case 'rhomboid': 
-// 			return {
-// 				width: 60,
-// 				height: 60,
-// 				// angle:-45,
-// 				data: {
-// 					key
-// 				},
-// 				attrs: {
-// 					body: {
-// 						stroke: border.borderColor,
-// 						strokeWidth: border.width,
-// 						fill: border.fill,
-// 						strokeDasharray: null,
-// 						refPoints: '0,10 10,0 20,10 10,20',
-// 					},
-// 					text: {
-// 						fill: text.color,
-// 						fontSize: text.size,
-// 						lineHeight: text.lineHeight,
-// 						fontWeight: 'normal',
-// 						textWrap: {
-// 							width: -10,
-// 						},
-// 					}
-// 				},
-// 				ports: {
-// 					items: [
-// 							{ group: 'port-top', id: 'p_top' },
-// 							{ group: 'port-bottom', id: 'p_bottom' },
-// 							{ group: 'port-left', id: 'p_left' },
-// 							{ group: 'port-right', id: 'p_right' },
-// 					],
-// 					groups: {
-// 							"port-top": {
-// 									position: 'top',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-bottom": {
-// 									position: 'bottom',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-left": {
-// 									position: 'left',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 							"port-right": {
-// 									position: 'right',
-// 									zIndex: 20,
-// 									...portStyle
-// 							},
-// 					}
-// 				},
-// 			}
-// 		case 'text': 
-// 			return {
-// 				width: 60,
-// 				height: 40,
-// 				data: {
-// 					key,
-// 				},
-// 				attrs: {
-// 					rect: {
-// 						stroke: '',
-// 						strokeWidth: 0,
-// 						fill: 'transparent',
-// 					},
-// 					text: {
-// 						text: '文本框',
-// 						fontSize: text.size,
-// 						lineHeight: text.lineHeight,
-// 						fontWeight: 'normal',
-// 						fill: text.color,
-// 						textWrap: {
-// 							width: -10,
-// 						},
-// 					}
-// 				},
-// 			}
-// 	}
-// }
+/**type--类型  xP--定位点的横坐标 yP--定位点的纵坐标
+ * 创建的线条
+ * 斜直线无箭头、斜直线单项箭头、斜直线双线箭头
+ * 弯折线无箭头、弯折线单项、弯折线双向箭头
+ * 圆角弯折线无箭头、圆角弯折线单项、圆角弯折线双向箭头
+ */
+export const myEdgeOption = (type,xP=0,yP=0) => {
+  // 斜直线
+  let skewLine={
+    source: { x: xP-40, y: yP-40 },
+    target: { x: xP+40 ,y: yP+40 },
+    router: {
+      name: 'normal',
+      args: {
+        padding: {
+          left: 10,
+        }
+      }
+    },
+    attrs:{
+      line:{
+        stroke: line.color,
+        strokeWidth: line.width,
+        sourceMarker: false,//起始箭头 
+        targetMarker: false,//终止箭头
+      }
+    }
+  }
+  //弯折线
+  let bendLine={
+    source: { x: xP-40, y: yP-40 },
+    target: { x: xP+40 ,y: yP+40 },
+    vertices:[{x:xP,y:yP-40},{x:xP,y:yP+40}],
+    attrs:{
+      line:{
+        stroke: line.color,
+        strokeWidth: line.width,
+        sourceMarker: false,//起始箭头 
+        targetMarker: false,//终止箭头
+      }
+    }
+  }
+	switch (type) {
+		case 'noArrowStraight': 
+			return skewLine
+		case 'singleArrowStraight': 
+			return {
+				...skewLine,
+        attrs:{
+          line:{
+            stroke: line.color,
+            strokeWidth: line.width,
+            sourceMarker: false,//起始箭头 
+            targetMarker: "classic",//终止箭头
+          }
+        },
+			}
+		case 'doubleArrowStraight': 
+			return {
+				...skewLine,
+        attrs:{
+          line:{
+            stroke: line.color,
+            strokeWidth: line.width,
+            sourceMarker: "classic",//起始箭头 
+            targetMarker: "classic",//终止箭头
+          }
+        },
+			}
+		case 'noArrowBend': 
+			return bendLine
+		case 'singleArrowBend': 
+			return {
+        ...bendLine,
+        attrs:{
+          line:{
+            stroke: line.color,
+            strokeWidth: line.width,
+            sourceMarker: false,//起始箭头 
+            targetMarker: "classic",//终止箭头
+          }
+        },
+			}
+    case 'doubleArrowBend':
+      return {
+        ...bendLine,
+        attrs:{
+          line:{
+            stroke: line.color,
+            strokeWidth: line.width,
+            sourceMarker: "classic",//起始箭头 
+            targetMarker: "classic",//终止箭头
+          }
+        },
+      }
+    case 'noArrowBoundBend': 
+			return {
+        ...bendLine,
+        connector: {
+          name: 'rounded',
+          args: { radius: 8 },
+        },
+      }
+    case 'singleArrowBoundBend': 
+			return {
+        ...bendLine,
+        connector: {
+          name: 'rounded',
+          args: { radius: 8 },
+        },
+        attrs:{
+          line:{
+            stroke: line.color,
+            strokeWidth: line.width,
+            sourceMarker: false,//起始箭头 
+            targetMarker: "classic",//终止箭头
+          }
+        },
+      }
+    case 'doubleArrowBoundBend': 
+			return {
+        ...bendLine,
+        connector: {
+          name: 'rounded',
+          args: { radius: 8 },
+        },
+        attrs:{
+          line:{
+            stroke: line.color,
+            strokeWidth: line.width,
+            sourceMarker: 'classic',//起始箭头 
+            targetMarker: "classic",//终止箭头
+          }
+        },
+      }
+  }
+}
 

+ 45 - 53
src/views/sandbox_manage/common/events.js

@@ -55,12 +55,12 @@ export const myEvents = (graph) => {
 			}
 
 			// 动态增加框的高度
-			edit_area.oninput = () => {
-				const domH = (edit_area.getBoundingClientRect().height) /zoom;
-				node.size(width,domH > 50 ? domH : 50);
-				// node.size(width,domH > height ? domH : height);
+			// edit_area.oninput = () => {
+			// 	const domH = (edit_area.getBoundingClientRect().height) /zoom;
+			// 	node.size(width,domH > 50 ? domH : 50);
+			// 	// node.size(width,domH > height ? domH : height);
 
-			}
+			// }
 
 			//失焦后设置内容
 			edit_area.onblur = () => {
@@ -69,7 +69,8 @@ export const myEvents = (graph) => {
 				node.attr('text/text', newval);
 				
 				const domH = (edit_area.getBoundingClientRect().height) /zoom;
-				node.size(width,domH > 50 ? domH : 50);
+				// node.size(width,domH > 50 ? domH : 50);
+				node.size(width,domH);
 				
 				$('#sand-chart-container')[0].removeChild(edit_area);
 			}
@@ -159,62 +160,53 @@ export const myEvents = (graph) => {
 	
 		// 	selected.length ? store.commit('sand/SET_SELECT_CELL',selected[0]) : store.commit('sand/SET_SELECT_CELL',null);
 		// })
-		// 鼠标 Hover 时添加小工具
-		// graph.on('edge:mouseenter', ({ cell }) => {
-		// 	cell.addTools({
-		// 		name: 'vertices',
-		// 		tools: ['vertices'],
-		// 	})
-		// })
-
-		// graph.on('edge:mouseleave', ({ cell }) => {
-		// 	if (cell.hasTools('onhover')) {
-		// 		cell.removeTools()
-		// 	}
-		// })
 		graph.on('edge:mouseenter', ({ cell }) => {
-			cell.addTools([
-				{
-					name: 'source-arrowhead',
-					args: {
-						attrs:{
-							d: 'M 8 -6 -8 0 8 6 Z',
-							fill: line.color
+			console.log(cell.store.data);
+			if(cell.store.data.shape=="mindmap-edge"){
+				// 思维导图的边
+			}else{
+				cell.addTools([
+					{
+						name: 'source-arrowhead',
+						args: {
+							attrs:{
+								d: 'M 8 -6 -8 0 8 6 Z',
+								fill: line.color
+							}
 						}
-					}
-				},
-				{
-					name: 'target-arrowhead',
-					args: {
-						attrs:{
-							d: 'M -8 -6 8 0 -8 6 Z',
-							fill: line.color
+					},
+					{
+						name: 'target-arrowhead',
+						args: {
+							attrs:{
+								d: 'M -8 -6 8 0 -8 6 Z',
+								fill: line.color
+							}
 						}
-					}
-				},
-				// {
-				// 	name: 'vertices',
-				// 	args:{
-				// 		addable:false,
-				// 	},
-				// }
-				{
-					name: 'segments',
-					args: {
-						snapRadius: 20,
 					},
-				}
-			])
+					{
+						name:"vertices",
+						args:{
+							addable:false,
+							removable:false
+						}
+					},
+					{
+						name: 'segments'
+					}
+				])
+			}
+
 		})
 		
 		graph.on('edge:mouseleave', ({ cell }) => {
-			cell.removeTools()
+			if(cell.store.data.shape=="mindmap-edge"){
+				// 思维导图的边
+			}else{
+				cell.removeTools()
+			}
 		})
 
-		// graph.on('graph:mouseup', (e) => {
-		// 	console.log(e,'mouseup');
-		// })
-		// console.log(document.getElementById('sand-chart-container'));
 }
 
 /* 绑定键盘事件 */

+ 5 - 8
src/views/sandbox_manage/common/gragh.js

@@ -25,10 +25,10 @@ export function myGraph (wrapper) {
 			multiple: false
 		},
 		snapline: true, //对齐线
-		panning: { //画布拖动
-			enabled: true,
-			eventTypes: ['leftMouseDown', 'rightMouseDown', 'mouseWheel']
-		},
+		// panning: { //画布拖动
+		// 	enabled: true,
+		// 	eventTypes: ['leftMouseDown', 'rightMouseDown', 'mouseWheel']
+		// },
 		clipboard: true,
 		keyboard: {
 			enabled: true,
@@ -114,10 +114,7 @@ export function myGraph (wrapper) {
         minimap: {
             enabled: true,
             container: document.getElementById("minimap"),
-        },
-				interacting:{
-					arrowheadMovable:true
-				}
+        }
 	})
 
 	/* 节点操作事件 */

+ 367 - 0
src/views/sandbox_manage/common/mindmap.js

@@ -0,0 +1,367 @@
+import { Graph, Cell, Node, Path } from '@antv/x6'
+import Hierarchy from '@antv/hierarchy'
+
+// 中心主题
+Graph.registerNode(
+  'topic',          
+  {
+    inherit: 'rect',
+    markup: [
+      {
+        tagName: 'rect',
+        selector: 'body',
+      },
+      {
+        tagName: 'image',
+        selector: 'img',
+      },
+      {
+        tagName: 'text',
+        selector: 'label',
+      },
+    ],
+    attrs: {
+      body: {
+        rx: 6,
+        ry: 6,
+        stroke: '#5F95FF',
+        fill: '#EFF4FF',
+        strokeWidth: 1,
+      },
+      img: {
+        ref: 'body',
+        refX: '100%',
+        refY: '50%',
+        refY2: -8,
+        width: 16,
+        height: 16,
+        'xlink:href':
+          'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SYCuQ6HHs5cAAAAAAAAAAAAAARQnAQ',
+        event: 'add:topic',
+        class: 'topic-image',
+      },
+      label: {
+        fontSize: 14,
+        fill: '#262626',
+      },
+    },
+  },
+  true,
+)
+
+// 分支主题
+Graph.registerNode(
+  'topic-child',
+  {
+    inherit: 'rect',
+    markup: [
+      {
+        tagName: 'rect',
+        selector: 'body',
+      },
+      {
+        tagName: 'text',
+        selector: 'label',
+      },
+      {
+        tagName: 'path',
+        selector: 'line',
+      },
+    ],
+    attrs: {
+      body: {
+        fill: '#ffffff',
+        strokeWidth: 0,
+        stroke: '#5F95FF',
+      },
+      label: {
+        fontSize: 14,
+        fill: '#262626',
+        textVerticalAnchor: 'bottom',
+      },
+      line: {
+        stroke: '#5F95FF',
+        strokeWidth: 2,
+        d: 'M 0 15 L 60 15',
+      },
+    },
+  },
+  true,
+)
+
+// 连接器
+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,
+)
+
+const data = {
+  id: Math.random()+"",
+  type: 'topic',
+  label: '中心主题',
+  width: 160,
+  height: 50,
+  children: [
+    {
+      id: Math.random()+'-1',
+      type: 'topic-branch',
+      label: '分支主题1',
+      width: 100,
+      height: 40,
+      children: [
+        {
+          id: Math.random()+'-1-1',
+          type: 'topic-child',
+          label: '子主题1',
+          width: 60,
+          height: 30,
+        },
+        {
+          id: Math.random()+'-1-2',
+          type: 'topic-child',
+          label: '子主题2',
+          width: 60,
+          height: 30,
+        },
+      ],
+    },
+    {
+      id: Math.random()+'-2',
+      type: 'topic-branch',
+      label: '分支主题2',
+      width: 100,
+      height: 40,
+    },
+  ],
+}
+
+let graphIn;
+
+export const setGraph=(graph)=>{
+  graphIn = graph
+
+  graphIn.on('add:topic', ({ node }) => {
+    const { id } = node
+    const type = node.prop('type')
+    if (addChildNode(id, type)) {
+      render()
+    }
+  })
+  // graphIn.bindKey(['backspace', 'delete'], () => {
+  //   const selectedNodes = graphIn.getSelectedCells().filter((item) => item.isNode())
+  //   if (selectedNodes.length) {
+  //     const { id } = selectedNodes[0]
+  //     if (removeNode(id)) {
+  //       render()
+  //     }
+  //   }
+  // })
+  
+  graphIn.bindKey('tab', (e) => {
+    e.preventDefault()
+    const selectedNodes = graphIn.getSelectedCells().filter((item) => item.isNode())
+    if (selectedNodes.length) {
+      const node = selectedNodes[0]
+      const type = node.prop('type')
+      if (addChildNode(node.id, type)) {
+        render()
+      }
+    }
+  })
+}
+
+export const render = (position) => {
+  console.log("addaddaddaddaddadd");
+  // data.x = position.x
+  // data.y = position.y
+  const result = Hierarchy.mindmap(data, {
+    direction: 'H',
+    getHeight(d) {
+      console.log(d,'getHeight');
+      return d.height
+    },
+    getWidth(d) {
+      return d.width
+    },
+    getHGap() {
+      return 40
+    },
+    getVGap() {
+      return 20
+    },
+    getSide: () => {
+      return 'right'
+    },
+    center:[0,0]
+  })
+  const cells = []
+  let xGap = position?position.x-result.x:0
+  let yGap = position?position.y-result.y:0
+
+  console.log(yGap,xGap,'datadatadata');
+
+  // console.log(position.x-result.x,position.y-result.y);
+
+  // result.x = position.x
+  // result.y = position.y
+  const traverse = (hierarchyItem) => {
+    if (hierarchyItem) {
+      const { data, children } = hierarchyItem
+      console.log(data.id,'hierarchyItemhierarchyItemhierarchyItem');
+      cells.push(
+        graphIn.createNode({
+          id: data.id,
+          shape: data.type === 'topic-child' ? 'topic-child' : 'topic',
+          x: xGap+hierarchyItem.x,
+          y: yGap+hierarchyItem.y,
+          width: data.width,
+          height: data.height,
+          label: data.label,
+          type: data.type,
+        }),
+      )
+      if (children) {
+        children.forEach((item) => {
+          const { id, data } = item
+          cells.push(
+            graphIn.createEdge({
+              shape: 'mindmap-edge',
+              source: {
+                cell: hierarchyItem.id,
+                anchor:
+                  data.type === 'topic-child'
+                    ? {
+                        name: 'right',
+                        args: {
+                          dx: -16,
+                        },
+                      }
+                    : {
+                        name: 'center',
+                        args: {
+                          dx: '25%',
+                        },
+                      },
+              },
+              target: {
+                cell: id,
+                anchor: {
+                  name: 'left',
+                },
+              },
+            }),
+          )
+          traverse(item)
+        })
+      }
+    }
+  }
+  traverse(result)
+  console.log(graphIn);
+  console.log(cells);
+  graphIn.addCell(cells)
+  // graphIn.resetCells(cells)
+  // graphIn.centerContent()
+}
+
+const findItem = (obj,id) => {
+  if (obj.id === id) {
+    return {
+      parent: null,
+      node: obj,
+    }
+  }
+  const { children } = obj
+  if (children) {
+    for (let i = 0, len = children.length; i < len; i++) {
+      const res = findItem(children[i], id)
+      if (res) {
+        return {
+          parent: res.parent || obj,
+          node: res.node,
+        }
+      }
+    }
+  }
+  return null
+}
+
+const addChildNode = (id, type) => {
+  const res = findItem(data, id)
+  const dataItem = res && res.node
+  if (dataItem) {
+    let item = null
+    const length = dataItem.children ? dataItem.children.length : 0
+    if (type === 'topic') {
+      item = {
+        id: `${id}-${length + 1}`,
+        type: 'topic-branch',
+        label: `分支主题${length + 1}`,
+        width: 100,
+        height: 40,
+      }
+    } else if (type === 'topic-branch') {
+      item = {
+        id: `${id}-${length + 1}`,
+        type: 'topic-child',
+        label: `子主题${length + 1}`,
+        width: 60,
+        height: 30,
+      }
+    }
+    if (item) {
+      if (dataItem.children) {
+        dataItem.children.push(item)
+      } else {
+        dataItem.children = [item]
+      }
+      return item
+    }
+  }
+  return null
+}
+
+const removeNode = (id) => {
+  const res = findItem(data, id)
+  const dataItem = res && res.parent
+  if (dataItem && dataItem.children) {
+    const { children } = dataItem
+    const index = children.findIndex((item) => item.id === id)
+    return children.splice(index, 1)
+  }
+  return null
+}
+
+// render()

+ 12 - 8
src/views/sandbox_manage/common/node.js

@@ -1,7 +1,11 @@
 import { configOpt } from './toolConfig';
+import store from "@/vuex/index"
 
 const { line,border,text } = configOpt;
 
+console.log(store,'storestorestore');
+const styleConfig=store.state.sand.styleConfig
+
 //定义图形
 const configStyles = {
 	rect: {
@@ -111,10 +115,10 @@ export const myNodeOption = (key) => {
 					key
 				},
 				attrs: {
-					rect: {
+					body: {
 						stroke: border.borderColor,
 						strokeWidth: border.width,
-						fill: border.fill,
+						fill:styleConfig.backgroundColor,
 						strokeDasharray: null,
 					},
 					text: {
@@ -170,10 +174,10 @@ export const myNodeOption = (key) => {
 					key
 				},
 				attrs: {
-					rect: {
+					body: {
 						stroke: border.borderColor,
 						strokeWidth: border.width,
-						fill: border.fill,
+						fill: styleConfig.backgroundColor,
 						strokeDasharray: null,
 						rx:8,
 						ry:8
@@ -227,10 +231,10 @@ export const myNodeOption = (key) => {
 					key
 				},
 				attrs: {
-					ellipse: {
+					body: {
 						stroke: border.borderColor,
 						strokeWidth: border.width,
-						fill: border.fill,
+						fill: styleConfig.backgroundColor,
 						strokeDasharray: null,
 					},
 					text: {
@@ -290,7 +294,7 @@ export const myNodeOption = (key) => {
 					body: {
 						stroke: border.borderColor,
 						strokeWidth: border.width,
-						fill: border.fill,
+						fill: styleConfig.backgroundColor,
 						strokeDasharray: null,
 						refPoints: '0,10 10,0 20,10 10,20',
 					},
@@ -343,7 +347,7 @@ export const myNodeOption = (key) => {
 					key,
 				},
 				attrs: {
-					rect: {
+					body: {
 						stroke: '',
 						strokeWidth: 0,
 						fill: 'transparent',

+ 19 - 0
src/views/sandbox_manage/common/toolConfig.js

@@ -34,4 +34,23 @@ export const sizeOptions = [
 	14,
 	12,
 	10,
+]
+
+export const styleSettings=[
+	{
+		id:1,
+		backgroundColor:'#DAE8FF'
+	},
+	{
+		id:2,
+		backgroundColor:'orange'
+	},
+	{
+		id:3,
+		backgroundColor:'purple'
+	},
+	{
+		id:4,
+		backgroundColor:'red'
+	}
 ]

+ 105 - 95
src/views/sandbox_manage/sandFlowNew/index.vue

@@ -7,16 +7,15 @@
             <div class="sand-elements sand-elements-line">
               <span>线条</span>
               <div class="elements-row" >
-                <!-- <img :src="edge.ImgUrl" v-for="edge in myEdges" :key="edge.key"
-                @mousedown="edgeDragStart(edge,$event)" /> -->
                 <img src="~@/assets/icons/arrow.svg" :draggable="true" @dragstart="edgeDragStart('noArrowStraight',$event)" />
-                <img src="~@/assets/img/chart_m/change.png" />
-                <img src="~@/assets/img/chart_m/Group.png" />
-                <img src="~@/assets/img/chart_m/Group_act.png" />
-                <img src="~@/assets/img/chart_m/User.png" />
-                <img src="~@/assets/img/chart_m/User_act.png" />
-                <img src="~@/assets/img/chart_m/View.png" />
-                <img src="~@/assets/img/chart_m/View_act.png" />
+                <img src="~@/assets/img/chart_m/change.png" :draggable="true" @dragstart="edgeDragStart('singleArrowStraight',$event)" />
+                <img src="~@/assets/img/chart_m/Group.png" :draggable="true" @dragstart="edgeDragStart('doubleArrowStraight',$event)"/>
+                <img src="~@/assets/img/chart_m/Group_act.png" :draggable="true" @dragstart="edgeDragStart('noArrowBend',$event)"/>
+                <img src="~@/assets/img/chart_m/User.png" :draggable="true" @dragstart="edgeDragStart('singleArrowBend',$event)"/>
+                <img src="~@/assets/img/chart_m/User_act.png" :draggable="true" @dragstart="edgeDragStart('doubleArrowBend',$event)"/>
+                <img src="~@/assets/img/chart_m/View.png" :draggable="true" @dragstart="edgeDragStart('noArrowBoundBend',$event)"/>
+                <img src="~@/assets/img/chart_m/View_act.png" :draggable="true" @dragstart="edgeDragStart('singleArrowBoundBend',$event)"/>
+                <img src="~@/assets/img/chart_m/View_act.png" :draggable="true" @dragstart="edgeDragStart('doubleArrowBoundBend',$event)"/>
               </div>
             </div>
             <div class="sand-elements sand-elements-shape">
@@ -36,20 +35,21 @@
             <div class="sand-elements sand-elements-mind">
               <span>思维导图</span>
               <div class="elements-row-mind">
-                <img src="~@/assets/icons/arrow.svg" />
-                <img src="~@/assets/icons/arrow.svg" />
-                <img src="~@/assets/icons/arrow.svg" />
-                <img src="~@/assets/icons/arrow.svg" />
-                <img src="~@/assets/icons/arrow.svg" />
-                <img src="~@/assets/icons/arrow.svg" />
-                <img src="~@/assets/icons/arrow.svg" />
+                <img src="~@/assets/img/totaladdgoodcount.png" :draggable="true" @dragstart="edgeDragStart('singleMindmap',$event)"/>
+                <img src="~@/assets/img/totalfavoritecount.png" :draggable="true" @dragstart="edgeDragStart('doubleMindmap',$event)"/>
               </div>
             </div>
           </div>
 
         </el-tab-pane>
         <el-tab-pane label="风格" name="风格">
-          风格
+          <div class="sand-style-tab">
+            <img src="~@/assets/img/totalfavoritecount.png" :class="styleActive==1?'active':''"
+             @click="changeStyle(1)"/>
+            <img src="~@/assets/img/totaladdgoodcount.png" :class="styleActive==2?'active':''" @click="changeStyle(2)" />
+            <img src="~@/assets/img/fanscount.png" :class="styleActive==3?'active':''" @click="changeStyle(3)"/>
+            <img src="~@/assets/img/workscount.png" :class="styleActive==4?'active':''" @click="changeStyle(4)"/>
+          </div>
         </el-tab-pane>
       </el-tabs>
     </div>
@@ -97,9 +97,11 @@
 <script>
 import { myGraph } from '../common/gragh';
 import { myNodes,myNodeOption } from '../common/node';
-import { myEdges } from '../common/edge';
+import { myEdgeOption } from '../common/edge';
 import { Addon } from '@antv/x6'
 import { configOpt } from '../common/toolConfig';
+import {setGraph,render} from "../common/mindmap"
+import {styleSettings} from "../common/toolConfig"
 
 const { line} = configOpt;
   export default {
@@ -109,10 +111,9 @@ const { line} = configOpt;
         graph: null,
         dnd:null,
         initData: {},
-        activeToolTabName:"元素库",
+        activeToolTabName:"风格",
         addEdgeType:"",
-        tx:0,
-        ty:0
+        styleActive:1
       }
     },
     watch: {
@@ -125,15 +126,18 @@ const { line} = configOpt;
       myNodes(){
         return myNodes
       },
-      myEdges(){
-        return myEdges
+      myEdgeOption(){
+        return myEdgeOption
       }
     },
     mounted(){
       this.init()
-      console.log(document.getElementsByClassName('x6-graph-scroller-content')[0].clientWidth);
-      document.getElementsByClassName('x6-graph-scroller-content')[0].addEventListener("dragover",this.edgeDragover)
-      document.getElementsByClassName('x6-graph-scroller-content')[0].addEventListener("drop",this.edgeDrop)
+      document.getElementById('sand-mainBody-chart').addEventListener("dragover",this.edgeDragover)
+      document.getElementById('sand-mainBody-chart').addEventListener("drop",this.edgeDrop)
+      // console.log(document.getElementsByClassName('x6-graph-scroller-content')[0]);
+      // document.getElementsByClassName('x6-graph-scroller-content')[0].addEventListener("dragover",this.edgeDragover)
+      // document.getElementsByClassName('x6-graph-scroller-content')[0].addEventListener("drop",this.edgeDrop)
+      
     },
     beforeDestroy(){
       document.getElementById('sand-mainBody-chart').removeEventListener("dragover",this.edgeDragover)
@@ -151,11 +155,7 @@ const { line} = configOpt;
             return true;
           },
         });
-        // graph.on('translate', ({ tx, ty }) => {
-        //   this.tx = tx
-        //   this.ty = ty
-        //   console.log(tx, ty);
-        // })
+        setGraph(graph)
 		  },
       dragStart(data,e) {
         // console.log(data,e,"触发了")
@@ -167,7 +167,8 @@ const { line} = configOpt;
         });
         this.dnd.start(node,e);
       },
-      edgeDragStart(type){
+      edgeDragStart(type,e){
+        console.log(e);
         this.addEdgeType = type
         console.log(type,"触发了边")
       },
@@ -180,65 +181,54 @@ const { line} = configOpt;
         }
         console.log(this.addEdgeType,e);
         console.log(this.graph);
-        // console.log(e.offsetX-this.tx,e.offsetY-this.ty);
-        // return 
-        this.graph.addEdge({
-          shape:'edge',
-          // shape,
-          // ...myNodeOption(key),
-          // source: { x: 240, y: 40 },
-          // source: { x: e.screenX-40, y: e.screenX-40 },
-          // target: { x: e.screenY+40, y: e.screenY+40 },
-          // source: { x: 0, y: 0 },
-          // target: { x: 0 ,y: 80 },
-          source: { x: e.offsetX, y: e.offsetY },
-          target: { x: e.offsetX ,y: e.offsetY+80 },
-          router: {
-            name: 'normal',
-            args: {
-              padding: {
-                left: 10,
+        let position = this.graph.clientToLocal({x:e.clientX,y:e.clientY})
+
+        if(this.addEdgeType.indexOf("Mindmap")!==-1){
+          //插入思维导图
+          console.log("插入思维导图");
+          render(position)
+        }else{
+          this.graph.addEdge({
+            shape:'edge',
+            ...this.myEdgeOption(this.addEdgeType,position.x,position.y)
+          });
+        }
+
+        
+      },
+      changeStyle(activeNum){
+        this.$store.commit("sand/SET_CELL_STYLE",activeNum)
+        let styleData=styleSettings[activeNum-1]
+
+        let cells = this.graph.getCells()
+        // console.log(cells);
+
+        for (let i = 0; i < cells.length; i++) {
+          const element = cells[i];
+          console.log(element);
+          if(element.shape=="edge") continue
+          if(element.data.key == 'text'){
+            // element.attrs.text.fill=styleData.backgroundColor
+            element.setAttrs({
+              text:{
+                fill:styleData.backgroundColor
               }
-            }
-          },
-          attrs:{
-            line:{
-              stroke: line.color,
-							strokeWidth: line.width,
-              sourceMarker: false,//起始箭头 
-							targetMarker: false,//终止箭头
-            }
-          },
-          connector: {
-            name: 'normal',
-          },
-          // tools: {
-          //   items: [
-          //     {
-          //       name: 'vertices',
-          //       args: {
-          //         attrs: { fill: '#666' },
-          //       },
-          //     },
-          //     // {
-          //     //   name: 'segments',
-          //     //   args: {
-          //     //     snapRadius: 20,
-          //     //     attrs: {
-          //     //       fill: '#444',
-          //     //     },
-          //     //   },
-          //     // },
-          //   ],
-          // },
-          // vertices: [{ x: 240, y: 140 }]
-        });
+            })
+          }else{
+            element.setAttrs({
+              body:{
+                fill:styleData.backgroundColor
+              }
+            })
+          }
+        }
+        this.styleActive = activeNum
       },
       copySandHandle(){
 
       },
       saveChart(){
-        console.log(this.myEdges);
+        console.log(this.myEdgeOption);
       }
     },
   }
@@ -292,18 +282,29 @@ const { line} = configOpt;
         .sand-elements-mind{
           border-bottom: none;
           padding-bottom: 0;
-          .elements-row-mind{
-            display: flex;
-            flex-wrap: wrap;
-            align-items: center;
-            justify-content: space-between;
-            img{
-              width: calc(50% - 10px);
-            }
-          }
         }
 
       }
+      .elements-row-mind,.sand-style-tab{
+        display: flex;
+        flex-wrap: wrap;
+        align-items: center;
+        justify-content: space-between;
+        img{
+          width: calc(50% - 10px);
+        }
+      }
+      .sand-style-tab{
+        padding: 20px 30px;
+        img{
+          border: 1px solid #C8CDD9;
+          margin-bottom: 20px;
+          cursor: pointer;
+        }
+        .active{
+          border: 1px solid #0052D9;
+        }
+      }
     }
     .sand-main{
       flex: 1;
@@ -420,5 +421,14 @@ const { line} = configOpt;
       height: auto !important;
     }
   }
-
+  .topic-image {
+    visibility: hidden;
+    cursor: pointer;
+  }
+  .x6-node:hover .topic-image {
+    visibility: visible;
+  }
+  .x6-node-selected rect {
+    stroke-width: 2px;
+  }
 </style>

+ 13 - 2
src/vuex/modules/sand.js

@@ -1,5 +1,5 @@
 // 沙盘
-import { configOpt } from '@/views/sandbox_manage/common/toolConfig';
+import { configOpt,styleSettings } from '@/views/sandbox_manage/common/toolConfig';
 
 const sand = {
 	namespaced: true,
@@ -11,6 +11,11 @@ const sand = {
 		DisableLine: true, //禁用线条设置
 		DisableBorder: true, //禁用线框设置
 		selectCell: null,
+		// 不同风格
+		style:1,
+		styleConfig:{
+			backgroundColor:"#DAE8FF",
+		}
 	}),
   mutations: {
 		/* 节点选中 toolbar设置状态 */
@@ -69,8 +74,14 @@ const sand = {
 		SET_BOLD_STYLE(state,{attr,val}) {
 			state.initConfig.text.fontWeight = val;
 			state.selectCell.attr(`${attr}`,val);
+		},
+		// 设置节点风格
+		SET_CELL_STYLE(state,style){
+			if(!style) style=1
+			state.style = style
+			let styleData = styleSettings[style-1]
+			state.styleConfig.backgroundColor = styleData.backgroundColor
 		}
-
 	},
   actions: {