使用jsPlumb插件實現動態連線功能

這周去看了兩天的羽毛球亞錦賽,工做有提早晚上加班作一些,可是技術文章卻拉下了。
這段時間一直在尋找能夠實現前端元素動態連線的功能,找了好幾個庫,考慮過用d3或者原生svg和canvas來實現,最後和同項目的同事商量後決定使用jsPlumb插件庫來作。
jsPlumb是一個強大的JavaScript連線庫,它能夠將html中的元素用箭頭、曲線、直線等鏈接起來,適用於開發Web上的圖表、建模工具等,其實jsPlumb可能主要是用來作流程圖的,它在實現這方面的功能上很是強大,我在項目中只使用了它少部分功能,來實現項目中連線的效果。javascript


 
連線效果
initJSPlumb = () => { this.jsp = jsPlumb.getInstance({ //錨點位置;對任何沒有聲明描點的Endpoint設置錨點,用於source及target節點 Anchor: ["Right", "Left"], Anchors: ["Right", "Left"], //連線的source和target Anchor ConnectionsDetachable: false, //連線是否可用鼠標分離 ConnectionOverlays: [ //連線的疊加組件,如箭頭、標籤 ["Arrow", { //箭頭參數設置 location: 1, visible: true, width: 11, length: 11, id: "ARROW", events: { click: function () { } } }], ["Label", { //標籤參數設置 location: 0.1, id: "label", cssClass: "aLabel", //hover時label的樣式名 events: { tap: function () { } }, visible: true }] ], Connector: "Bezier", //連線的類型,流程圖(Flowchart)、貝塞爾曲線等 //父級元素id;假如頁面元素所在上層不一樣,最外層父級必定要設置 Container: "module", //若是請求不存在的Anchor、Endpoint或Connector,是否拋異常 DoNotThrowErrors: false, //經過jsPlumb.draggable拖拽元素時的默認參數設置 DragOptions: {cursor: 'pointer', zIndex: 2000}, DropOptions: {}, //target Endpoint放置時的默認參數設置 Endpoint: "Dot", //端點(錨點)的樣式聲明 //用jsPlumb.connect建立鏈接時,source端點和target端點的樣式設置 Endpoints: [null, null], EndpointOverlays: [], //端點的疊加物 //端點的默認樣式 EndpointStyle: {fill: 'transparent', stroke: '#1565C0', radius: 4, strokeWidth: 1}, EndpointStyles: [null, null], //連線的source和target端點的樣式 //端點hover時的樣式 EndpointHoverStyle: {fill: '#1565C0', stroke: '#1565C0', radius: 4, strokeWidth: 1}, //連線的source和target端點hover時的樣式 EndpointHoverStyles: [null, null], //連線hover時的樣式 HoverPaintStyle: {stroke: '#1565C0', strokeWidth: 3}, LabelStyle: {color: "black"}, //標籤的默認樣式,用css寫法。 LogEnabled: false, //是否開啓jsPlumb內部日誌 Overlays: [], //連線和端點的疊加物 MaxConnections: 10, //端點支持的最大鏈接數 //連線樣式 PaintStyle: {stroke: '#1565C0', strokeWidth: 1, joinstyle: 'round'}, ReattachConnections: true, //是否從新鏈接使用鼠標分離的線? RenderMode: "svg", //默認渲染模式 Scope: "jsPlumb_DefaultScope", //範圍,具備相同scope的點纔可鏈接 reattach: true, }) this.jsp.bind('beforeDrop', this.jspBeforeDrop) } 

以上是初始化jsPlumb對象的函數。
接下來獲取數據,加載頁面的系統和編制模塊。css

fetchDataForLeft(data) {
    var jsonString_left = '[{"module_name":"crm系統","module_id":"A","nodes":[{"id":"A-1","text":"開始","position":"left"},{"id":"A-2","text":"過程","position":"left"},{"id":"A-3","text":"過程ing","position":"left"}]},{"module_name":"財務系統","module_id":"B","nodes":[{"id":"B-1","text":"開始","position":"left"}]}]'; var jsonString_right = '[{"module_name":"年度預算編制","module_id":"C","nodes":[{"id":"C-1","text":"結束","position":"right"}]},{"module_name":"營收編制","module_id":"D","nodes":[{"id":"D-1","text":"結束","position":"right"}]}]'; // var nodeData_left = JSON.parse(jsonString_left); //[{"entity":null,"id":"934D62BD0F8249B09F29EC9FA051E390","code":"1","name":"CRM????","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"81ABCD2890E2460B90A9B8A0ACE3FABD","code":null,"name":"CRM系統","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"9AE1B07886E54F3DB0082D46392DE774","code":null,"name":"CRM系統","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"E6D29376AC86455DBC3518D12F28C5B0","code":null,"name":"CRM系統","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null}] var nodeData_left = data; this.setState({ nodes_left: nodeData_left, }) //繪製左邊點 nodeData_left.map((node, index) => { this.setState({datas: node, nodes: node.fromModelList}, () => { this.initNodes(this.refs.nodes_left[index], 'left'); // this.initEdges(nodeData.edges); }); }) //繪製右邊點 // nodeData_right.map((node, index) => { // this.setState({data_right: node, node_right: node.toModelList}, () => { // this.initNodes(this.refs.nodes_right[index], 'right'); // // this.initEdges(nodeData.edges); // }); // }) } fetchDataForRight(data){ var jsonString_left = '[{"module_name":"crm系統","module_id":"A","nodes":[{"id":"A-1","text":"開始","position":"left"},{"id":"A-2","text":"過程","position":"left"},{"id":"A-3","text":"過程ing","position":"left"}]},{"module_name":"財務系統","module_id":"B","nodes":[{"id":"B-1","text":"開始","position":"left"}]}]'; var jsonString_right = '[{"module_name":"年度預算編制","module_id":"C","nodes":[{"id":"C-1","text":"結束","position":"right"}]},{"module_name":"營收編制","module_id":"D","nodes":[{"id":"D-1","text":"結束","position":"right"}]}]'; // var nodeData_left = JSON.parse(jsonString_left); //[{"entity":null,"id":"934D62BD0F8249B09F29EC9FA051E390","code":"1","name":"CRM????","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"81ABCD2890E2460B90A9B8A0ACE3FABD","code":null,"name":"CRM系統","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"9AE1B07886E54F3DB0082D46392DE774","code":null,"name":"CRM系統","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null},{"entity":null,"id":"E6D29376AC86455DBC3518D12F28C5B0","code":null,"name":"CRM系統","systemType":null,"databaseType":null,"hostName":null,"databaseaName":null,"userName":null,"password":null,"created":null,"modified":null}] var nodeData_right = data; this.setState({ nodes_right: nodeData_right }) //繪製右邊點 nodeData_right.map((node, index) => { this.setState({data_right: node, node_right: node.toModelList}, () => { this.initNodes(this.refs.nodes_right[index], 'right'); // this.initEdges(nodeData.edges); }); }) } 

初始化鏈接錨點html

initNodes = (node, position) => { this.jsp.setSuspendDrawing(true); if (position === "left") { DynamicAnchors.map(anchor => this.rjsp.addEndpoint(node, anEndpoint, {anchor: "Right"})); } else { DynamicAnchors_Right.map(anchor => this.rjsp.addEndpoint(node, anEndpoint, {anchor: "Left"})); } this.rjsp.setSuspendDrawing(false, true); } 

//自動連線前端

initEdges = (edges) => { this.rjsp.setSuspendDrawing(true); edges.map(edge => { this.jsp.connect(edge, Common); }) this.jsp.setSuspendDrawing(false, true); } 
相關文章
相關標籤/搜索