天天看點

JS元件系列——JsPlumb流程圖及相關效果詳解

前言:之前項目裡面用到了Web裡面的拖拽流程圖的技術JsPlumb,其實真不算難,不過項目裡面用HTML做的一些類似flash的效果,感覺還不錯,在此分享下。

Jsplumb官網:https://jsplumbtoolkit.com

GitHub:https://github.com/sporritt/jsplumb/

一、效果圖展示

 1、從左邊拖動元素到中間區域,然後連線

JS元件系列——JsPlumb流程圖及相關效果詳解

 2、連線類型可以自定義:這裡定義為直線、折線、曲線。實際項目中根據業務我們定義為分裝線、分裝支線、總裝線等

JS元件系列——JsPlumb流程圖及相關效果詳解

 3、滑鼠拖動區域選中元素,并且選中元素統一拖動位置。

JS元件系列——JsPlumb流程圖及相關效果詳解
JS元件系列——JsPlumb流程圖及相關效果詳解
JS元件系列——JsPlumb流程圖及相關效果詳解

 4、對選中的元素左對齊。

JS元件系列——JsPlumb流程圖及相關效果詳解

5、對選中元素居中對齊

JS元件系列——JsPlumb流程圖及相關效果詳解

6、右對齊

JS元件系列——JsPlumb流程圖及相關效果詳解

7、上對齊

JS元件系列——JsPlumb流程圖及相關效果詳解

8、垂直居中對齊

JS元件系列——JsPlumb流程圖及相關效果詳解

9、下對齊

JS元件系列——JsPlumb流程圖及相關效果詳解

10、根據第一個選中的元素上下靠攏

JS元件系列——JsPlumb流程圖及相關效果詳解

11、根據第一個選中的元素左右靠攏

JS元件系列——JsPlumb流程圖及相關效果詳解

12、根據第一個選中的元素同高

JS元件系列——JsPlumb流程圖及相關效果詳解

13、根據第一個選中的元素同寬

JS元件系列——JsPlumb流程圖及相關效果詳解

14、選中元素順時針旋轉,點選一次旋轉45度

JS元件系列——JsPlumb流程圖及相關效果詳解
JS元件系列——JsPlumb流程圖及相關效果詳解

15、選中元素逆時針旋轉。

JS元件系列——JsPlumb流程圖及相關效果詳解

16、選中統一删除元素以及元素上面的連線

JS元件系列——JsPlumb流程圖及相關效果詳解

這裡很多效果其實在項目中作用并不太大,很多單純就是為了展示用的。沒辦法,上司要求,我們就隻有做喽。

二、代碼詳解

 這裡涉及的效果比較多,可能要分多篇來介紹。這篇還是來看看構造流程圖的核心技術:JsPlumb。

1、概述

關于JsPlumb的内容,園子裡也有很多朋友做過分享,也有寫得不錯的博文。在此就簡單說明下吧。jsPlumb是一個強大的JavaScript連線庫,它可以将html中的元素用箭頭、曲線、直線等連接配接起來,适用于開發Web上的圖表、模組化工具等。它同時支援jQuery+jQuery UI、MooTools和YUI3這三個JavaScript架構,十分強大。本項目中還是結合大家最熟悉的JQuery來講解。并且還要注意的一點就是JsPlumb的浏覽器相容性,JsPlumb支援IE 6以上、火狐、谷歌等各種浏覽器

2、使用

(1)引入JS檔案

可以直接去官網上面下載下傳最新的js庫,由于JsPlumb需要JQuery的支援,按照網上的說法,它隻相容jQuery1.3.x及以上版本,并在jQuery UI 1.7.x、1.8.x及1.9.x上測試通過。是以我們需要下載下傳較高一點版本的JQuery和JQuery UI。關于JsPlumb的内容隻需要引用一個Js即可。類似

<script src="~/Content/jquery-1.9.1.min.js"></script>     <script src="~/Content/jquery-ui-1.11.4.custom/jquery-ui.js"></script>     <link href="~/Content/jquery-ui-1.11.4.custom/jquery-ui.min.css" rel="stylesheet" />     <script src="~/Content/jsPlumb-master/dist/js/jquery.jsPlumb-1.7.5.js"></script>      

(2)初始化

使用JsPlumb需要注意一點,JsPlumb的連線的樣式是由點确定的,也就是說點的樣式裡面包含了相關的屬性來說明當使用此點來連線的時候,連線的樣式應該是什麼樣的。

在我們項目裡面,左邊的模型區域,中間才是設計區域。那麼要将一個元素從模型區域建立出來,就要用到我們JQuery UI裡面的draggable和droppable事件。首先我們注冊左邊模型的draggable和中間區域的droppable事件。

cshtml頁面代碼,<div id="divContentLeftMenu">這個是左邊模型的容器,<div id="divCenter"></div>表示中間區域容器。

      <div id="divContentLeftMenu">                 <div class="sidebar-menu" id="divSidebar">                     <a href="#plantmodel" onclick="Resize()" class="nav-header menu-first collapsed" data-toggle="collapse">工廠模型</a>                     <ul id="plantmodel" class="nav nav-list collapse menu-second">                     </ul>                     <a href="#artlinemodel" onclick="Resize()" class="nav-header menu-first collapsed" data-toggle="collapse">工藝段模型</a>                     <ul id="artlinemodel" class="nav nav-list collapse menu-second">                         <li>                             <a href="#">                                 <div class="node radius" id="node4" dbtype="DTO_TM_ART_LINE">                                     <label>工段</label>                                 </div>                             </a>                         </li>                         <li>                             <a href="#">                                 <div class="node" id="node5" dbtype="DTO_TM_ULOC">                                     <label>工位</label>                                 </div>                             </a>                         </li>                     </ul>                 </div>             </div>             <div id="divCenter"></div>      

Js代碼:

首先我們定義幾個點的樣式的全局變量

//基本連接配接線樣式     var connectorPaintStyle = {         strokeStyle: "#1e8151",         fillStyle: "transparent",         radius: 5,         lineWidth: 2     };     // 滑鼠懸浮在連接配接線上的樣式     var connectorHoverStyle = {         lineWidth: 3,         strokeStyle: "#216477",         outlineWidth: 2,         outlineColor: "white"     };     var endpointHoverStyle = {         fillStyle: "#216477",         strokeStyle: "#216477"     };     //空心圓端點樣式設定     var hollowCircle = {         DragOptions: { cursor: 'pointer', zIndex: 2000 },         endpoint: ["Dot", { radius: 7 }],  //端點的形狀         connectorStyle: connectorPaintStyle,//連接配接線的顔色,大小樣式         connectorHoverStyle: connectorHoverStyle,         paintStyle: {             strokeStyle: "#1e8151",             fillStyle: "transparent",             radius: 5,             lineWidth: 2         },        //端點的顔色樣式         //anchor: "AutoDefault",         isSource: true,    //是否可以拖動(作為連線起點)         connector: ["Straight", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }],  //連接配接線的樣式種類有[Bezier],[Flowchart],[StateMachine ],[Straight ]         isTarget: true,    //是否可以放置(連線終點)         maxConnections: -1,    // 設定連接配接點最多可以連接配接幾條線         connectorOverlays: [["Arrow", { width: 10, length: 10, location: 1 }]]     };      

然後再頁面初始化完成之後注冊事件

        $(function(){                     //左邊區域的draggable事件                     $("#divContentLeftMenu .node").draggable({                         helper: "clone",                         scope: "plant"                     });                     //中間拖拽區的drop事件                     $("#divCenter").droppable({                         scope: "plant",                         drop: function (event, ui) {                             // 建立工廠模型到拖拽區                             CreateModel(ui, $(this));                         }                     });             });      
//1.建立模型(參數依次為:drop事件的ui、目前容器、id、目前樣式)      function CreateModel(ui, selector) {             //1.1 添加html模型             var modelid = $(ui.draggable).attr("id");             i++;             var id = modelid + i;             var cur_css = modelid;             var type = $(ui.helper).attr("dbtype");             $(selector).append('<div class="node ' + cur_css + '" id="' + id + '" dbtype="' + type + '" parentid="' + $(selector).attr("id") + '" onclick="oInitElement.GetPropertiesByType(\'' + type + '\',this)" ondblclick="InitStation().DbClick(\'' + type + '\',this)" >' + $(ui.helper).html() + '</div>');             var left = parseInt(ui.offset.left - $(selector).offset().left);             var top = parseInt(ui.offset.top - $(selector).offset().top);             $("#" + id).css("left", left).css("top", top);             //jsPlumb.setContainer($("#divCenter"));             //1.2 添加連接配接點             jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);             jsPlumb.addEndpoint(id, { anchors: "LeftMiddle" }, hollowCircle);             jsPlumb.addEndpoint(id, { anchors: "TopCenter" }, hollowCircle);             jsPlumb.addEndpoint(id, { anchors: "BottomCenter" }, hollowCircle);             jsPlumb.draggable(id);             //1.3 注冊實體可draggable和resizable             $("#" + id).draggable({                 containment: "parent",                 start: function () {                     startMove();                 },                 drag: function (event, ui) {                     MoveSelectDiv(event, ui, id);                     jsPlumb.repaintEverything();                 },                 stop: function () {                     jsPlumb.repaintEverything();                 }             });             $("#" + id).resizable({                 resize: function () {                     jsPlumb.repaintEverything();                 },                 stop: function () {                     jsPlumb.repaintEverything();                     //oInitElement.SendPropRequest("DTO_TM_PLANT", $(this));                 }             });             return id;         };      

重點來看看這一句:

jsPlumb.addEndpoint(id, { anchors: "RightMiddle" }, hollowCircle);      

調用了JsPlumb裡面的addEndpoint方法,第一個參數表示頁面标簽的id,第一個表示連線點的位置(RightMiddle、LeftMiddle、TopCenter、BottomCenter四個選項);第三參數表示點的樣式以及連線的樣式。沒調用依次addEndpoint方法,元素上面就會多一個連線的節點。關于hollowCircle裡面各個參數的意義,可以檢視api。

還有一句多個地方都看到了:

jsPlumb.repaintEverything();      

看字面意思大概能知道這句是幹什麼的,修複所有。當在中間區域拖動元素的時候,如果不帶這一句,節點不會跟着元素一起移動。加上之後節點才會跟随标簽移動。至此,最基礎的JsPlumb連線就完成了。源碼在下篇。

js