流程图(HTML5拖拽)

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4     <head>
  5         <meta charset="UTF-8">
  6         <title>Document</title>
  7         <style type="text/css">
  8             #d1 {
  9                 width: 800px;
 10                 height: 800px;
 11                 border: 1px solid #ccc;
 12                 position: relative;
 13                 background: #fafafa;
 14             }
 15             
 16             #d1>div {
 17                 width: 130px;
 18                 height: 30px;
 19                 border: 1px solid #ccc;
 20                 border-radius: 8px;
 21                 position: absolute;
 22                 z-index: 2;
 23                 text-align: center;
 24                 line-height: 30px;
 25                 background: #fff;
 26             }
 27             
 28             #d1>svg {
 29                 width: 100%;
 30                 height: 100%;
 31                 position: absolute;
 32                 z-index: 1
 33             }
 34             
 35             .input .point {
 36                 position: absolute;
 37                 border: 6px solid transparent;
 38                 border-top: 6px solid #ccc;
 39                 top: 0px;
 40                 left: 58px;
 41             }
 42             
 43             .input .circle {
 44                 position: absolute;
 45                 width: 10px;
 46                 height: 10px;
 47                 border: 1px solid #ccc;
 48                 top: -7px;
 49                 left: 60px;
 50                 border-radius: 50%;
 51                 background: #fff;
 52             }
 53             
 54             .output .circle {
 55                 position: absolute;
 56                 width: 15px;
 57                 height: 15px;
 58                 border: 1px solid #ccc;
 59                 bottom: -10px;
 60                 left: 57px;
 61                 border-radius: 50%;
 62                 background: #fff;
 63                 cursor: crosshair;
 64                 z-index: 10;
 65             }
 66             
 67             .output .circle:hover {
 68                 background: #FC9901;
 69             }
 70         </style>
 71     </head>
 72 
 73     <body>
 74         <ul class="shuiguo">
 75             <li draggable="true" data-name="ps1">ps1</li>
 76             <li draggable="true" data-name="ps2">ps2</li>
 77             <li draggable="true" data-name="ps3">ps3</li>
 78             <li draggable="true" data-name="ps4">ps4</li>
 79             <li draggable="true" data-name="switch">switch</li>
 80         </ul>
 81         <div id="d1">
 82             <svg>
 83                 
 84             </svg>
 85         </div>
 86         <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
 87         <script type="text/javascript">
 88             var dragData = [];
 89             //重置拖拽后流程图展示
 90             function reload(isend) {
 91                 $(function() {
 92                     var html = "";
 93                     var g = `
 94                     <defs>
 95                         <marker id="markerArrow1" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
 96                             <path d="M0,1 L0,5 L3,3 z" fill="#CCCCCC"></path> 
 97                         </marker>
 98                         <marker id="markerArrow2" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
 99                             <path d="M0,1 L0,5 L3,3 z" fill="#cccdff"></path> 
100                         </marker>
101                         <marker id="markerArrow3" markerWidth="10" markerHeight="10" refX="3" refY="2.6" orient="auto" markerUnits="strokeWidth">
102                             <path fill="#f00" d="m6.75848,4.22161c-0.13193,0.12924 -0.3468,0.12924 -0.47903,0l-3.03436,-2.97252c-0.13193,-0.12953 -0.13223,-0.33974 0,-0.46927c0.13163,-0.12953 0.3465,-0.12953 0.47933,0l3.03406,2.97223c0.13193,0.13012 0.13253,0.34003 0,0.46956l0,0l0,0zm-0.00361,-2.974l-3.03406,2.97223c-0.13253,0.12983 -0.3471,0.12983 -0.47933,0c-0.13223,-0.12924 -0.13223,-0.33915 0.0003,-0.46927l3.03406,-2.97193c0.13253,-0.12953 0.3474,-0.12953 0.47903,-0.0003c0.13253,0.12953 0.13193,0.33974 0,0.46927l0,0l0,0z"/>
103                         </marker>
104                     </defs>
105                     `;
106                     if($('svg').siblings()) { //清除$('svg')范围外的所有元素
107                         var prev = $('svg').siblings();
108                         for(var i = 0; i < prev.length; i++) {
109                             prev[i].remove();
110                         }
111                     }
112                     console.log(dragData);
113                     for(var i = 0; i < dragData.length; i++) { //循环dragData,重置流程图所有dom节点
114                         if(dragData[i] != undefined) {
115                             var data = dragData[i];
116                             html +=
117                                 `
118                             <div class = "${data.name}" data-drag="1" data-id = "${data.id}" data-inx = "${data.inx}" data-iny = "${data.iny}" data-label = "${data.label}" ondragstart = "insideDrag(this)"  draggable = "true" style = "transform:translate(${data.x}px,${data.y}px)">
119                                 <span class = "${data.icon}" data-id = "${data.id}"></span>
120                                 <span data-id = "${data.id}">${data.label}</span>
121                                 <div class = "output">
122                                     <span class = "circle" title = "输出" onmousedown = "noDrag(this)" onmouseup = "addDrag(this)" onmouseleave = "draw(this)" onmouseenter = "noMove()" data-id = "${data.id}"></span>
123                                 </div>
124                             </div>  
125                         `
126                             if(data.link.length > 0) {
127                                 for(var j = 0; j < data.link.length; j++) {
128                                     g +=
129                                         `
130                                         <g id="${data.link[j].name}">
131                                             <path style="cursor:pointer" d = "M${data.outx} ${data.outy} Q${data.link[j].mx1} ${data.link[j].my1} ${data.link[j].mx2} ${data.link[j].my2} T${data.link[j].dx} ${data.link[j].dy}" stroke = "#CCCCCC" fill = "none" stroke-width="4" marker-end="url(#markerArrow1)"/>
132                                         </g>
133                                         `
134                                 }
135                             }
136                         }
137                     }
138                     $('svg').before(html);
139                     $('svg').html(g);
140                     if(isend) {
141                         $('svg').on('mouseenter', "path", function() {
142                             $(this).attr({
143                                 "stroke": "#cccdff",
144                                 "marker-end": "url(#markerArrow2)",
145                                 "marker-mid": "url(#markerArrow3)"
146                             })
147                         }).on('mouseleave', "path", function() {
148                             $(this).attr({
149                                 "stroke": "#cccccc",
150                                 "marker-end": "url(#markerArrow1)",
151                                 "marker-mid": ""
152                             })
153                         }).on('click', "path", function() {
154                             var $p = $(this).parent();
155                             var id = $p[0].id;
156                             for(var i = 0; i < dragData.length; i++) {
157                                 var data = dragData[i];
158                                 for(var j = 0; j < data.link.length; j++) {
159                                     if(id == data.link[j].name) {
160                                         data.link.splice(j, 1)
161                                     }
162                                 }
163                                 for(var j = 0; j < data.linked.length; j++) {
164                                     if(id == data.linked[j].name) {
165                                         data.linked.splice(j, 1)
166                                     }
167                                 }
168                             }
169                             $p.remove()
170                         });
171                     } else {
172                         $('svg').off('mouseenter mouseleave', "path");
173                     }
174                     console.log($('svg').siblings());
175                 })
176             }
177             //reload();
178             document.getElementById('d1').ondragover = function(e) {
179                 e.preventDefault(); //流程图展示区阻止默认事件
180             }
181             var dWidth = Number($('#d1').css('width').slice(0, -2)); //流程图展示区域宽度
182             console.log(dWidth);
183             var dHeight = Number($('#d1').css('height').slice(0, -2)); //流程图展示区域高度
184             console.log(dHeight);
185             var dClient = $("#d1").offset().top; //流程图展示区偏移位置top
186             var dLeft = $("#d1").offset().left; //流程图展示区偏移位置left
187             console.log('顶部位置', dClient);
188             console.log('左边位置', dLeft);
189 
190             //模块拖进流程图后,初始化拖拽方法
191             /*
192              * word:模块名称
193              * name:模块数据名称
194              * type:拖拽事件类型,用于判断来执行不同拖拽事件,"outside":拖拽完成,"inside":开始拖拽
195              * id:模块id
196              */
197             function drag(word, name, type, id) {
198                 console.log(type);
199                 console.log(name);
200                 //在可拖动元素放置在 <div> 元素中时执行事件ondrop
201                 document.getElementById('d1').ondrop = function(e) {
202                     var sTop = $(document).scrollTop(); //文档滚动条偏移量top
203                     var sLeft = $(document).scrollLeft(); //文档滚动条偏移量left
204                     console.log('e.target', e.target.dataset.id);
205                     var x, y;
206                     console.log('e.clientX', e.clientX);
207                     console.log('e.clientY', e.clientY);
208                     if((dWidth - e.clientX + dLeft + 65) - sLeft >= 132) {
209                         x = e.clientX - 65 - dLeft + sLeft;
210                     } else {
211                         x = dWidth - 133;
212                     }
213                     if((e.clientX - dLeft) < 65) {
214                         x = 1;
215                     }
216                     if((dHeight - e.clientY + dClient + 15) - sTop >= 33) {
217                         y = e.clientY - 15 - dClient + sTop;
218                     } else {
219                         y = dHeight - 33;
220                     }
221                     if(e.clientY - 15 - dClient + sTop < 0) {
222                         y = 1;
223                     }
224                     if(type == "outside") {
225                         console.log('放下了');
226                         dragData.push({
227                             id: dragData.length,
228                             label: word,
229                             name: name,
230                             x: x, //模块相对展示区域的位移x
231                             y: y, //模块相对展示区域的位移y
232                             outx: x + 68, //模块输出点位置x/贝塞尔曲线起点x
233                             outy: y + 30, //模块输出点位置y/贝塞尔曲线起点y
234                             inx: x + 65, //模块输入点位置x
235                             iny: y - 1, //模块输入点位置y
236                             link: [], //存放由该模块连接的关联线数据数组
237                             linked: [], //存放由其他模块连接该模块的关联线数据数组
238                             dx: 0,
239                             dy: 0,
240                             mx1: 0,
241                             my1: 0,
242                             mx2: 0,
243                             my2: 0,
244                             style: name,
245                             draw: false,
246                             icon: name + "Icon"
247                         });
248                         console.log(dragData);
249                         reload(1);
250                     }
251                     if(type == "inside") {
252                         console.log(word, name, type, id);
253                         for(var i = 0; i < dragData.length; i++) {
254                             if(id == dragData[i].id) {
255                                 dragData[i].x = x;
256                                 dragData[i].y = y;
257                                 dragData[i].outx = dragData[i].x + 68;
258                                 dragData[i].outy = dragData[i].y + 30;
259                                 dragData[i].inx = dragData[i].x + 65;
260                                 dragData[i].iny = dragData[i].y - 1;
261                                 console.log('dragData[i].link', dragData[i].link);
262                                 for(let j = 0; j < dragData[i].link.length; j++) {
263                                     dragData[i].link[j].linkId = parseFloat(dragData[i].link[j].name.split("|")[1]);
264                                 }
265                                 for(var k = 0; k < dragData[i].linked.length; k++) {
266                                     console.log('dragData[i].linked[k]', dragData[i].linked[k]);
267                                     for(let j = 0; j < dragData.length; j++) {
268                                         if(dragData[i].linked[k].linkedNum == dragData[j].id) {
269                                             console.log('ID一样了啊');
270                                             for(let m = 0; m < dragData[j].link.length; m++) {
271                                                 if(dragData[i].linked[k].name == dragData[j].link[m].name) {
272                                                     console.log("名字一样了啊");
273                                                     dragData[j].link[m].dx = dragData[i].inx;
274                                                     dragData[j].link[m].dy = dragData[i].iny-10;
275                                                     dragData[j].link[m].mx1 = dragData[j].outx;
276                                                     dragData[j].link[m].my1 = dragData[j].link[m].dy > dragData[j].outy ? dragData[j].outy + (dragData[j].link[m].dy - dragData[j].outy) / 3 : dragData[j].outy - (dragData[j].link[m].dy - dragData[j].outy) / 3;
277                                                     dragData[j].link[m].mx2 = dragData[j].outx + (dragData[j].link[m].dx - dragData[j].outx) / 2,
278                                                     dragData[j].link[m].my2 = dragData[j].outy + (dragData[j].link[m].dy - dragData[j].outy) / 2
279                                                 }
280                                             }
281                                         }
282                                     }
283                                 }
284                                 if(dragData[i].link.length > 0) {
285                                     for(var j = 0; j < dragData[i].link.length; j++) {
286                                         dragData[i].link[j].mx1 = dragData[i].outx;
287                                         dragData[i].link[j].my1 = dragData[i].link[j].dy > dragData[i].outy ? dragData[i].outy + (dragData[i].link[j].dy - dragData[i].outy) / 3 : dragData[i].outy - (dragData[i].link[j].dy - dragData[i].outy) / 3;
288                                         dragData[i].link[j].mx2 = dragData[i].outx + (dragData[i].link[j].dx - dragData[i].outx) / 2,
289                                         dragData[i].link[j].my2 = dragData[i].outy + (dragData[i].link[j].dy - dragData[i].outy) / 2
290                                     }
291                                 }
292                             }
293                         }
294                         reload(1);
295                     }
296                 }
297             }
298             var shuiguo = $('.shuiguo li');
299             var isondrag = 0;
300             console.log(shuiguo);
301             for(var i = 0; i < shuiguo.length; i++) {
302                 console.log(shuiguo[i]);
303                 shuiguo[i].ondragstart = function() {
304                     console.log('东完了')
305                     drag(this.innerHTML, this.dataset.name, 'outside');
306                 }
307             }
308 
309             function insideDrag(item) {
310                 console.log(item);
311                 if(item.getAttribute('draggable')) {
312                     drag(item.dataset.label, item.className, 'inside', item.dataset.id);
313                 }
314             }
315 
316             function noDrag(item) {
317                 event.preventDefault();
318                 event.stopPropagation();
319                 console.log(item.parentNode.parentNode);
320                 var parent = item.parentNode.parentNode;
321                 parent.setAttribute('draggable', false);
322                 for(var i = 0; i < dragData.length; i++) {
323                     for(var d = 0; d < dragData[i].link.length; d++) {
324                         if(!~dragData[i].link[d].name.indexOf("|")) {
325                             dragData[i].link.splice(d, 1)
326                         }
327                     }
328                     if(parent.dataset.id == dragData[i].id) {
329                         dragData[i].draw = true;
330                         dragData[i].link.push({
331                             name: parent.dataset.id + parent.className,
332                             dx: 0,
333                             dy: 0,
334                             mx1: 0,
335                             my1: 0,
336                             mx2: 0,
337                             my2: 0
338                         });
339                         $('body').on('mouseup', function(e) {
340                             for(var j = 0; j < dragData.length; j++) {
341                                 if(parent.dataset.id == dragData[j].id) {
342                                     console.log('页面抬起了');
343                                     dragData[j].draw = false;
344                                     var $dom = $(e.target).data("drag") ? $(e.target) : $(e.target).closest("div[data-drag]");
345                                     if($dom.length) {
346                                         if($dom.data("drag") && $dom[0].dataset.id != dragData[j].id) { //判断是否关联另外模块,非自己
347                                             $('svg').unbind('mousemove');
348                                             var name = dragData[j].link[dragData[j].link.length - 1].name + "|" + $dom[0].dataset.id + $dom[0].className;
349                                             var isontbe = 0; //判断是否存在关联
350                                             for(let i = 0; i < dragData.length; i++) {
351                                                 if($dom[0].dataset.id == dragData[i].id) {
352                                                     for(let c = 0; c < dragData[i].linked.length; c++) {
353                                                         if(name == dragData[i].linked[c].name) {
354                                                             isontbe = 1
355                                                         }
356                                                     }
357                                                     if(!isontbe) { //不存在时候存入linked
358                                                         dragData[i].linked.push({
359                                                             name: name,
360                                                             linkedNum: parseFloat(name)
361                                                         })
362                                                     }
363                                                 }
364                                             }
365                                             if(!isontbe) { //不存在时候生成link数据
366                                                 dragData[j].link[dragData[j].link.length - 1].name = name;
367                                                 dragData[j].link[dragData[j].link.length - 1].dx = Number($dom[0].dataset.inx);
368                                                 dragData[j].link[dragData[j].link.length - 1].dy = Number($dom[0].dataset.iny)-10;
369                                             } else {
370                                                 dragData[j].link.splice(dragData[j].link.length - 1, 1);
371                                             }
372                                         } else {
373                                             dragData[j].link.splice(dragData[j].link.length - 1, 1);
374                                         }
375                                     } else {
376                                         dragData[j].link.splice(dragData[j].link.length - 1, 1);
377                                     }
378                                     $('svg').unbind('mousemove');
379                                     reload(1);
380                                 }
381                             }
382                             $('body').unbind('mouseup');
383                         })
384                         //reload();
385                     }
386                 }
387             }
388 
389             function addDrag(item) {
390                 var parent = item.parentNode.parentNode;
391                 parent.setAttribute('draggable', true);
392                 for(var i = 0; i < dragData.length; i++) {
393                     if(parent.dataset.id == dragData[i].id) {
394                         dragData[i].draw = false;
395                         console.log(dragData[i]);
396                     }
397                 }
398             }
399 
400             function draw(item) {
401                 var parent = item.parentNode.parentNode;
402                 parent.setAttribute('draggable', true);
403                 for(var i = 0; i < dragData.length; i++) {
404                     if(parent.dataset.id == dragData[i].id) {
405                         if(dragData[i].draw == true) {
406                             $('svg').mousemove(function(e) {
407                                 console.log(parent.dataset.id);
408                                 for(var i = 0; i < dragData.length; i++) {
409                                     if(parent.dataset.id == dragData[i].id) {
410                                         console.log(dragData[i]);
411                                         if(dragData[i].link[dragData[i].link.length - 1]) {
412                                             dragData[i].link[dragData[i].link.length - 1].dx = e.offsetX;
413                                             dragData[i].link[dragData[i].link.length - 1].dy = e.offsetY-10;
414                                             dragData[i].link[dragData[i].link.length - 1].mx1 = dragData[i].outx;
415                                             dragData[i].link[dragData[i].link.length - 1].my1 = dragData[i].dy > dragData[i].outy ? dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 3 : dragData[i].outy - (dragData[i].dy - dragData[i].outy) / 3;
416                                             dragData[i].link[dragData[i].link.length - 1].mx2 = dragData[i].outx + (dragData[i].dx - dragData[i].outx) / 2,
417                                             dragData[i].link[dragData[i].link.length - 1].my2 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 2
418                                         }
419                                         //////////////////////////////////////////////
420                                         dragData[i].dx = e.offsetX;
421                                         dragData[i].dy = e.offsetY-10;
422                                         dragData[i].mx1 = dragData[i].outx;
423                                         if(dragData[i].dy > dragData[i].outy) {
424                                             dragData[i].my1 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 3;
425                                         } else {
426                                             dragData[i].my1 = dragData[i].outy - (dragData[i].dy - dragData[i].outy) / 3;
427                                         }
428                                         dragData[i].mx2 = dragData[i].outx + (dragData[i].dx - dragData[i].outx) / 2
429                                         dragData[i].my2 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 2
430                                     }
431                                 }
432                                 reload();
433                                 console.log(2333);
434                             })
435                         } else {
436                             $('svg').unbind('mousemove');
437                         }
438 
439                     }
440                 }
441             }
442 
443             function noMove() {
444                 $('svg').unbind('mousemove');
445             }
446             $('svg').mouseup(function(e) {
447                 console.log(e.target);
448                 $('svg').unbind('mousemove');
449                 for(var i = 0; i < dragData.length; i++) {
450                     dragData[i].draw = false;
451                 }
452                 console.log('起来了');
453             })
454         </script>
455     </body>
456 
457 </html>

参考了http://blog.csdn.net/zhaoxiang66/article/details/78063271

根据大神的思路加强了功能,修复了bug

posted @ 2018-03-06 14:05  郑家好人  阅读(6806)  评论(0编辑  收藏  举报