天天看點

vue項目中如何使用有向無環圖(dag-diagram)

vue項目中如何使用有向無環圖(dag-diagram)

1、自定義右擊事件偶現問題

2、節點删除再添加反複操作幾次會出現,删除一個節點多個節點一起消失

3、檢測是否成環

關于有向無環圖在vue項目中的使用和安裝,已經有很多的文章有過介紹了,我在這就不再重複這些東西,本文主要介紹的是在使用dag-diagram(一下簡稱dag)這個插件時的小技巧或者說是一些經驗吧

<DAGBoard

:data-all="DataAll"

@updateDAG="updateDAG"

@editNodeDetails="editNodeDetails"

@doSthPersonal="doSthPersonal"

/>

插件中有一個doSthPersonal事件,就是用來自定義右擊事件的,可以在這個事件中寫你所要自定義的右擊事件的代碼,

但是有一個前提是你需要在每個節點的rightClickEvent中添加這個自定義事件的eventName和label

下面的代碼是dag插件中的源碼:

const rightClickEvent = this.DataAll.nodes[i].rightClickEvent || null

1

是以我們可以在自己的項目的updateDAG事件中這樣寫

this.DataAll.nodes[i].rightClickEvent = [

{

label: 'CREATE NODE',

eventName: 'creatednode',

},

label: 'DELETE NODE INFO',

eventName: 'deletenode',

];

如果隻是簡單的這樣寫上的話你會發現,自定義事件在你第一次去右擊的時候是不會出來的,但是第二次就會有了,這是因為updateDAG方法隻有節點在幕布内發生變化時(移動或删除)才會執行,在将節點拖入到幕布中的這一事件中是不會觸發的

是以我使用了watch來監聽this.DataAll.nodes的長度,來添加自定義事件,因為nodes的長度在節點被拖入幕布的時候就會發生變化

'DataAll.nodes.length': {

handler() {

for (let i = 0; i < this.DataAll.nodes.length; i += 1) {

}

deep: true,

這樣就可以解決第一次點選節點時,自定義事件不出現的問題

問題原因:

在dag插件中,每個節點的id都是由this.DataAll.nodes.length + 100組成的,如果你是删除節點的時候是先删除的最後添加的節點,那沒問題,但是如果删除的是非最後一個節點,那就會出現新添加的節點id和已存在的節點id重複的問題,是以當你移動新添加的節點或者删除新添加的節點時,會有另一個節點随之消失

解決方法:

是以在給節點id指派時我們應該添加一種情況

就是當使用者執行删除操作後,應該将id的值設定為最後添加的id值+1+100,這樣就不會出現有重複id的情況

if (this.DataAll.nodes.length) {

id1 = this.DataAll.nodes[len - 1].id + 1 - 100 + 100;

} else {

id1 = this.DataAll.nodes.length + 100;

this.DataAll.nodes.push({

...params.desp,

id: id1,

in_ports: [0, 1, 2, 3, 4],

out_ports: [0, 1, 2, 3, 4],

});

這個功能我在看插件源碼的時候它是有寫這部分校驗的,但是不知道為什麼我在dag這個項目中資料成環後并沒有提示,在我自己的項目中也并未實作改功能

于是我就把插件中的關于檢測是否成環這部分代碼拿出來,直接寫在了我自己的 項目中

其實用的還是插件中的源碼

// 檢測是否成環

this.DataAll.edges.forEach((item) => {

let isCircle = false;

// 出口 入口id

const { dst_node_id } = item; // eslint-disable-line

const checkCircle = (dstNodeId, nth) => {

if (nth > this.DataAll.nodes.length) {

isCircle = true;

return false;

if (item.src_node_id === dstNodeId) {

console.log(

'目标節點是',

item.src_node_id,

'次數為',

nth,

);

checkCircle(item.dst_node_id, ++nth); // eslint-disable-line

};

checkCircle(dst_node_id, 1);

if (isCircle) {

this.DataAll.edges.pop();

// alert('禁止成環');

this.$Message.error('禁止成環');

下一篇: 無向圖