vue項目中使用antvX6新手教程,附demo案例講解(可拖拽流程圖、網絡拓撲圖)

前言:

之前分別做了vue2和vue3項目里的網絡拓撲圖功能,發現對antv X6的講解博客比較少,最近終于得閑碼一篇了!

需求:

用戶可以自己拖拽節點,節點之間可以隨意連線,保存拓撲圖數據后傳給后端,然后在另一個頁面拿到之前的數據進行渲染展示。

最終成品如下圖:

一、準備工作:?

1、裝依賴

npm install --save @antv/x6

2、布局樣式

首先我們先規劃兩塊地方,左邊用來放可以拖的節點,右邊是antv X6的畫布,如下圖:(隨意做的demo,比較丑哈)

布局代碼:
<template><div class="dashboard-container"><p>選擇節點</p><div class="antvBox"><div class="menu-list"><div v-for="item in moduleList" :key="item.id"><img :src="item.image" alt="" /><p>{{ item.name }}</p></div></div><div class="canvas-card"><div id="container" /></div></div></div>
</template><script>
export default {name: "antvX6",data() {return {moduleList: [{id: 1,name: "節點1",image: require("@/assets/img/1.png"),},{id: 8,name: "節點2",image: require("@/assets/img/2.png"),},{id: 2,name: "節點3",image: require("@/assets/img/3.png"),},{id: 3,name: "節點4",image: require("@/assets/img/4.png"),},],};},
};
</script>
<style lang="scss" scoped>
.dashboard-container {.antvBox {display: flex;width: 100%;height: 100%;color: black;padding-top: 20px;.menu-list {height: 100%;width: 300px;padding: 0 10px;box-sizing: border-box;display: flex;justify-content: space-between;align-content: flex-start;flex-wrap: wrap;> div {margin-bottom: 10px;border-radius: 5px;padding: 0 10px;box-sizing: border-box;cursor: pointer;color: black;width: 105px;display: flex;flex-wrap: wrap;justify-content: center;img {height: 50px;width: 50px;}P {width: 90px;text-align: center;}}}.canvas-card {width: 1700px;height: 750px;box-sizing: border-box;> div {width: 1400px;height: 750px;border: 2px dashed #2149ce;}}}
}
</style>

3、添加拖拽事件

我們要先給左側圖標加一個拖拽結束的事件:

代碼如下:
draggable="true"
@dragend="handleDragEnd($event, item)"

在methods定義handleDragEnd函數:?

// 拖動后松開鼠標觸發事件handleDragEnd(e, item) {console.log(e, item); // 可以獲取到最后拖動后松開鼠標時的坐標和拖動的節點相關信息},
效果 :

這個時候我們可以去頁面試著拖動一個左邊的圖標,在鼠標松開時會看到控制臺輸出了節點相關信息,如下圖:

?以上就是準備工作了

二、使用antv X6

1、引入antv X6

import { Graph } from "@antv/x6";

2、初始化畫布

先在data(){}定義graph做畫布示例對象:

定義一個初始化函數,并且在mounted里面調用如下:

initGraph() {const container = document.getElementById("container");this.graph = new Graph({container: container, // 畫布容器width: container.offsetWidth, // 畫布寬height: container.offsetHeight, // 畫布高background: false, // 背景(透明)snapline: true, // 對齊線// 配置連線規則connecting: {snap: true, // 自動吸附allowBlank: false, // 是否允許連接到畫布空白位置的點allowMulti: true, // 是否允許在相同的起始節點和終止之間創建多條邊allowLoop: true, // 是否允許創建循環連線,即邊的起始節點和終止節點為同一節點highlight: true, // 拖動邊時,是否高亮顯示所有可用的節點highlighting: {magnetAdsorbed: {name: "stroke",args: {attrs: {fill: "#5F95FF",stroke: "#5F95FF",},},},},router: {// 對路徑添加額外的點name: "orth",},connector: {// 邊渲染到畫布后的樣式name: "rounded",args: {radius: 8,},},},panning: {enabled: false,},mousewheel: {enabled: true, // 支持滾動放大縮小zoomAtMousePosition: true,modifiers: "ctrl",minScale: 0.5,maxScale: 3,},grid: {type: "dot",size: 20, // 網格大小 10pxvisible: true, // 渲染網格背景args: {color: "#a0a0a0", // 網格線/點顏色thickness: 2, // 網格線寬度/網格點大小},},});},
 mounted() {this.initGraph();},

這里就是一些對畫布的配置,多數我都加了注釋,如有部分配置不懂可以評論區問我或者查官方文檔

3、畫布添加節點

代碼如下:

 //添加節點到畫布addHandleNode(x, y, id, image, name) {this.graph.addNode({id: id,shape: "image", // 指定使用何種圖形,默認值為 'rect'x: x,y: y,width: 60,height: 60,imageUrl: image,attrs: {body: {stroke: "#ffa940",fill: "#ffd591",},label: {textWrap: {width: 90,text: name,},fill: "black",fontSize: 12,refX: 0.5,refY: "100%",refY2: 4,textAnchor: "middle",textVerticalAnchor: "top",},},ports: {groups: {group1: {position: [30, 30],},},items: [{group: "group1",id: "port1",attrs: {circle: {r: 6,magnet: true,stroke: "#ffffff",strokeWidth: 2,fill: "#5F95FF",},},},],},zIndex: 10,});},

這里使用了antv X6提供的一個方法addNode,傳入的參數分別是:x坐標、y坐標、id節點唯一標識、image圖片、name節點名稱,我的案例這五種就夠了,如果有不同需求可以自己加

4、調用addHandleNode函數

在我們之前寫了的拖動節點結束后的函數(handleDragEnd)里面去調用上面那個函數,代碼如下:

// 拖動后松開鼠標觸發事件handleDragEnd(e, item) {console.log(e, item); // 可以獲取到最后拖動后松開鼠標時的坐標和拖動的節點相關信息this.addHandleNode(e.pageX - 500,e.pageY - 200,new Date().getTime(),item.image,item.name);},

以上所有操作做完應該就可以完成節點拖拽、連線功能:

5、上圖我們可以發現還差一些需求:

  • 節點上的那個藍色的連接樁一直顯示,有點遮擋圖標,也不太好看

  • 節點無法刪除

  • 節點之間的連線也無法刪除

這些都是需要點擊操作的事件,需要了解antv X6的事件系統,官方文檔貼圖如下

需求1:鼠標移入節點再顯示連接樁

定義一個函數nodeAddEvent,代碼如下:

nodeAddEvent() {const { graph } = this;const container = document.getElementById("container");const changePortsVisible = (visible) => {const ports = container.querySelectorAll(".x6-port-body");for (let i = 0, len = ports.length; i < len; i = i + 1) {ports[i].style.visibility = visible ? "visible" : "hidden";}};this.graph.on("node:mouseenter", () => {changePortsVisible(true);});this.graph.on("node:mouseleave", () => {changePortsVisible(false);});},

然后把這個函數在initGraph里面調用一下:

效果如下:

?

需求2:可以選中并刪除節點

想要的效果如下圖:

先在data(){}里面定義curSelectNode,然后在nodeAddEvent函數里加入以下代碼:

// 節點綁定點擊事件this.graph.on("node:click", ({ e, x, y, node, view }) => {console.log("點擊!!!", node);// 判斷是否有選中過節點if (this.curSelectNode) {// 移除選中狀態this.curSelectNode.removeTools();// 判斷兩次選中節點是否相同if (this.curSelectNode !== node) {node.addTools([{name: "boundary",args: {attrs: {fill: "#16B8AA",stroke: "#2F80EB",strokeWidth: 1,fillOpacity: 0.1,},},},{name: "button-remove",args: {x: "100%",y: 0,offset: {x: 0,y: 0,},},},]);this.curSelectNode = node;} else {this.curSelectNode = null;}} else {this.curSelectNode = node;node.addTools([{name: "boundary",args: {attrs: {fill: "#16B8AA",stroke: "#2F80EB",strokeWidth: 1,fillOpacity: 0.1,},},},{name: "button-remove",args: {x: "100%",y: 0,offset: {x: 0,y: 0,},},},]);}});

這里使用了antv X6的工具集,官方文檔貼圖如下:(需求3也使用了工具集)

需求3:可以選中并刪除節點間連線

?想要的效果如下:

在nodeAddEvent函數里加入以下代碼:

 // 連線綁定懸浮事件this.graph.on("cell:mouseenter", ({ cell }) => {if (cell.shape == "edge") {cell.addTools([{name: "button-remove",args: {x: "100%",y: 0,offset: {x: 0,y: 0,},},},]);cell.setAttrs({line: {stroke: "#409EFF",},});cell.zIndex = 99; // 保證當前懸停的線在最上層,不會被遮擋}});this.graph.on("cell:mouseleave", ({ cell }) => {if (cell.shape === "edge") {cell.removeTools();cell.setAttrs({line: {stroke: "black",},});cell.zIndex = 1; // 保證未懸停的線在下層,不會遮擋懸停的線}});

6、輸出拓撲圖信息

可以寫一個按鈕來保存拓撲圖信息,這里介紹以下兩個個人感覺常用的函數:

//保存畫布,并提交save() {console.log(this.graph.toJSON(), "graph");console.log(this.graph.getNodes(), "node");},

如上圖所示,點擊保存按鈕后 ,控制臺會輸出:

第一個是整個圖的信息,有節點有連線,可以自己展開看看里面的數據,第二個只有節點數據

四、總結

antv X6 是基于 HTML 和 SVG 的圖編輯引擎,提供低成本的定制能力和開箱即用的內置擴展,方便我們快速搭建 DAG 圖、ER 圖、流程圖、血緣圖等應用。

這里只是介紹了一種基礎拓撲圖的案例,也可以將節點image換成react,做一個編輯節點內文字的功能,就變成流程圖了。

查看官方文檔和示例,也很容易加入其他的功能

antv X6案例鏈接:https://x6.antv.antgroup.com/examples

api文檔:Graph | X6?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/719288.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/719288.shtml
英文地址,請注明出處:http://en.pswp.cn/news/719288.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

cPanel面板安裝付費的SSL證書

前不久遇到購買Hostease服務器的客戶反饋需要安裝SSL證書。因為安裝 SSL 證書不僅可以保護用戶數據安全&#xff0c;增加用戶信任度&#xff0c;提升搜索引擎排名&#xff0c;還有助于符合法規和標準&#xff0c;防止網絡攻擊。 安裝SSL證書可以通過如下步驟: 1. 選擇 SSL 證書…

數學建模【多元線性回歸模型】

一、多元線性回歸模型簡介 回歸分析是數據分析中最基礎也是最重要的分析工具&#xff0c;絕大多數的數據分析問題&#xff0c;都可以使用回歸的思想來解決。回歸分析的任務就是&#xff0c;通過研究自變量X和因變量Y的相關關系&#xff0c;嘗試去解釋Y的形成機制&#xff0c;進…

Linux配置網卡功能

提示:工具下載鏈接在文章最后 目錄 一.network功能介紹二.配置network功能2.1 network_ip配置檢查 2.2 network_br配置2.2.1 配置的網橋原先不存在檢查2.2.2 配置的網橋已存在-修改網橋IP檢查2.2.3 配置的網橋已存在-只添加網卡到網橋里檢查 2.3 network_bond配置檢查 2.4 netw…

Access AR Foundation 5.1 in Unity 2022

如果已經下載安裝了ARF但版本是5.0.7 可以通過下面的方式修改 修改后面的數字會自動更新 更新完成后查看版本 官方文檔 Access AR Foundation 5.1 in Unity 2021 | AR Foundation | 5.1.2

【知識整理】Git 使用實踐問題整理

問題1、fatal: refusing to merge unrelated histories 一、Git 的報錯 fatal: refusing to merge unrelated histories 新建了一個倉庫之后&#xff0c;把本地倉庫進行關聯提交、拉取的時候&#xff0c;出現了如下錯誤&#xff1a; fatal: master does not appear to be a g…

js原型原型鏈

js原型原型鏈 在 JavaScript 中&#xff0c;每個對象都有一個原型&#xff08;prototype&#xff09;。對象的原型是另一個對象的引用&#xff0c;它包含對象的共享屬性和方法。JavaScript 中的原型鏈則是對象之間通過原型鏈接起來的一種機制&#xff0c;用于實現繼承和屬性查找…

電腦無法開啟虛擬化

vm開啟虛擬化失敗 如果出現以下錯誤&#xff0c;需要進入bios界面&#xff0c;不同電腦進入界面的方式不一樣。這里以hp為例&#xff1a; 1、關機后&#xff0c;按住開機鍵和f10&#xff0c;進入如下界面&#xff08;語言在主菜單里面&#xff09; 2、選擇先進和下面的系統選…

c語言游戲實戰(10):坤坤的籃球回避秀

前言&#xff1a; 這款簡易版的球球大作戰是博主耗時兩天半完成的&#xff0c;玩家需要控制坤坤在游戲界面上移動&#xff0c;來躲避游戲界面上方不斷掉下來的籃球。本游戲使用C語言和easyx圖形庫編寫&#xff0c;旨在幫助初學者了解游戲開發的基本概念和技巧。 在開始編寫代…

Vue使用高德地圖定位到當前位置,并顯示天氣信息

首先得去高德控制臺申請兩個 key&#xff0c;一個天氣key和一個定位key 獲取天氣信息的函數&#xff1a; const getWeather function (city) {// 使用 fetch 發送請求獲取天氣信息fetch(https://restapi.amap.com/v3/weather/weatherInfo?city${city}&keyeefd36557b0250…

哪個有名的工具可以安全記事 私密記事本筆記推薦

在這個數字化的時代&#xff0c;我們的生活已經離不開各種記事工具。它們幫助我們記錄生活中的點點滴滴&#xff0c;無論是工作上的重要事項&#xff0c;還是個人的私密心情。然而&#xff0c;當我在尋找一個能夠安心記錄私密事情的工具時&#xff0c;安全性成為了我最關心的因…

C++從零開始的打怪升級之路(day42)

這是關于一個普通雙非本科大一學生的C的學習記錄貼 在此前&#xff0c;我學了一點點C語言還有簡單的數據結構&#xff0c;如果有小伙伴想和我一起學習的&#xff0c;可以私信我交流分享學習資料 那么開啟正題 今天分享的是關于繼承的知識點 1.菱形繼承 我們有許多關于繼承…

【軟件測試】Postman中變量的使用

Postman中可設置的變量類型有全局變量&#xff0c;環境變量&#xff0c;集合變量&#xff0c;數據變量及局部變量。區別則是各變量作用域不同&#xff0c;全局變量適用于所有集合&#xff0c;環境變量適用于當前所選環境&#xff08;所有集合中均可使用不同環境變量&#xff09…

【CSP試題回顧】202309-2-坐標變換(其二)

CSP-202309-2-坐標變換&#xff08;其二&#xff09; 關鍵點總結 1.輸入輸出的同步關閉&#xff0c;以加快I/O操作的速度 這一點還是很重要的&#xff0c;本題代碼如果不進行輸入輸出的同步關閉會時間超限。 ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);2.…

職場中的祖傳代碼處理建議

程序員是如何看待“祖傳代碼”的&#xff1f; 祖傳代碼的由來 在實際的程序員工作中&#xff0c;祖傳代碼是常見的。因為真正的互聯網職場生活中&#xff0c;業務變動調整頻繁&#xff0c;每到一個新的業務線&#xff0c;第一件事就是熟悉現有工程代碼&#xff0c;看舊文檔等…

K8S中POD的控制器

一、Pod控制器及其功用 Pod控制器&#xff0c;又稱之為工作負載&#xff08;workload&#xff09;&#xff0c;是用于實現管理pod的中間層&#xff0c;確保pod資源符合預期的狀態&#xff0c;pod的資源出現故障時&#xff0c;會嘗試進行重啟&#xff0c;當根據重啟策略無效&am…

Linux基礎命令[9]-wc

文章目錄 1. wc 命令說明2. wc 命令語法3. wc 命令示例3.1 不加參數3.2 -c&#xff08;統計字節數&#xff09;3.3 -m&#xff08;統計字符數&#xff09;3.4 -l&#xff08;統計行數&#xff09;3.5 -L&#xff08;最長一行的長度&#xff09;3.6 -w&#xff08;統計單詞數&am…

Arcgis實現點位空間位置從上到下從左到右排序

效果 背景 工作項目中經常會遇到需要對網格進行編號&#xff0c;而編號是有一定原則的&#xff0c;比如空間位置從上到下從左到右&#xff0c;或者其它原則&#xff0c;那么都可以通過下面的方式來實現 1、準備數據 點shp文件&#xff0c;查看初始FID字段標注&#xff0c;目…

transformer--transformer模型構建和測試

前面幾節進行了各種組件的學習和編碼&#xff0c;本節將組件組成transformer&#xff0c;并對其進行測試 EncoderDecoder 編碼器解碼器構建 使用EnconderDecoder實現編碼器-解碼器結構 # 使用EncoderDeconder類實現編碼器和解碼器class EncoderDecoder(nn.Module):def __ini…

飛書文檔批量導出

背景需求 最近所參與的項目即將結項&#xff0c;需要將飛書中的產品需求文檔&#xff08;PRD&#xff09;交付給甲方&#xff0c;由于文檔較多&#xff0c;大概有兩百多個&#xff0c;一個一個的下載導出&#xff0c;太麻煩了&#xff08;PS&#xff1a;本人比較懶&#xff09;…

ROS create_wall_timer/create_timer函數區別

在ROS&#xff08;Robot Operating System&#xff09;中&#xff0c;create_wall_timer 和 create_timer 是用于創建定時器的兩個不同的函數&#xff0c;它們在使用上有一些區別&#xff1a; Clock Type: create_wall_timer: 創建的定時器是基于Wall clock的&#xff0c;這意…