From da1afb7a045585efd04df1ec42d988ddcd5bff8c Mon Sep 17 00:00:00 2001 From: break60 <790061044@qq.com> Date: Tue, 17 Dec 2019 17:31:25 +0800 Subject: [PATCH] DAG automatic layout (#1497) * Password verification and v-for add key * DAG automatic layout --- .../src/js/conf/home/pages/dag/_source/dag.js | 238 ++++++++++++++++-- .../js/conf/home/pages/dag/_source/dag.vue | 47 +++- 2 files changed, 267 insertions(+), 18 deletions(-) diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.js b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.js index 0a86186933..11f22132c7 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.js +++ b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.js @@ -91,22 +91,232 @@ Dag.prototype.toolbarEvent = function ({ item, code, is }) { /** * Echo data display */ -Dag.prototype.backfill = function () { - jsPlumb.ready(() => { - JSP.init({ - dag: this.dag, - instance: this.instance +Dag.prototype.backfill = function (arg) { + if(arg) { + let locationsValue = store.state.dag.locations + let locationsValue1 = store.state.dag.locations + let locationsValue2 = store.state.dag.locations + let arr = [] + for (let i in locationsValue1) { + let objs = new Object(); + objs.id = i + arr.push(Object.assign(objs,locationsValue1[i])); //Attributes + } + let tmp = [] + for(let i in locationsValue2) { + if(locationsValue2[i].targetarr !='' && locationsValue2[i].targetarr.split(',').length>1) { + tmp.push(locationsValue2[i]) + } + } + + function copy (array) { + let newArray = [] + for(let item of array) { + newArray.push(item); + } + return newArray; + } + + + let newArr = copy(arr) + function getNewArr() { + for(let i= 0; i1) { + newArr[i].targetarr = newArr[i].targetarr.split(',').shift() + } + } + return newArr + } + getNewArr() + /** + * @description Transform flat data into a tree structure + * @param {Array} arr Flat data + * @param {String} pidStr targetarr key name + * @param {String} idStr id key name + * @param {String} childrenStr children key name + */ + function fommat({arrayList, pidStr = 'targetarr', idStr = 'id', childrenStr = 'children'}) { + let listOjb = {}; // Used to store objects of the form {key: obj} + let treeList = []; // An array to store the final tree structure data + // Transform the data into {key: obj} format, which is convenient for the following data processing + for (let i = 0; i < arrayList.length; i++) { + listOjb[arrayList[i][idStr]] = arrayList[i] + } + // Format data based on pid + for (let j = 0; j < arrayList.length; j++) { + // Determine if the parent exists + // let haveParent = arrayList[j].targetarr.split(',').length>1?listOjb[arrayList[j].targetarr.split(',')[0]]:listOjb[arrayList[j][pidStr]] + let haveParent = listOjb[arrayList[j][pidStr]] + if (haveParent) { + // If there is no parent children field, create a children field + !haveParent[childrenStr] && (haveParent[childrenStr] = []) + // Insert child in parent + haveParent[childrenStr].push(arrayList[j]) + } else { + // If there is no parent, insert directly into the outermost layer + treeList.push(arrayList[j]) + } + } + return treeList + } + let datas = fommat({arrayList: newArr,pidStr: 'targetarr'}) + // Count the number of leaf nodes + function getLeafCountTree(json) { + if(!json.children) { + json.colspan = 1; + return 1; + } else { + let leafCount = 0; + for(let i = 0 ; i < json.children.length ; i++){ + leafCount = leafCount + getLeafCountTree(json.children[i]); + } + json.colspan = leafCount; + return leafCount; + } + } + // Number of tree node levels + let countTree = getLeafCountTree(datas[0]) + function getMaxFloor(treeData) { + let floor = 0 + let v = this + let max = 0 + function each (data, floor) { + data.forEach(e => { + e.floor = floor + e.x=floor*170 + if (floor > max) { + max = floor + } + if (e.children) { + each(e.children, floor + 1) + } + }) + } + each(treeData,1) + return max + } + getMaxFloor(datas) + // The last child of each node + let lastchildren = []; + forxh(datas); + function forxh(list) { + for (let i = 0; i < list.length; i++) { + let chlist = list[i]; + if (chlist.children) { + forxh(chlist.children); + } else { + lastchildren.push(chlist); + } + } + } + // Get all parent nodes above the leaf node + function treeFindPath (tree, func, path,n) { + if (!tree) return [] + for (const data of tree) { + path.push(data.name) + if (func(data)) return path + if (data.children) { + const findChildren = treeFindPath(data.children, func, path,n) + if (findChildren.length) return findChildren + } + path.pop() + } + return [] + } + function toLine(data){ + return data.reduce((arr, {id, name, targetarr, x, y, children = []}) => + arr.concat([{id, name, targetarr, x, y}], toLine(children)), []) + return result; + } + let listarr = toLine(datas); + let listarrs = toLine(datas) + let dataObject = {} + for(let i = 0; i value2) { + return 1; + } else { + return 0; + } + }; + } + + lastchildren = lastchildren.sort(createComparisonFunction('x')) + + // Coordinate value of each leaf node + for(let a = 0; a data.targetarr===lastchildren[i].targetarr,[],i+1) + for(let j = 0; j1) { + dataObject[Object.keys(locationsValue1)[0]].y = (countTree/2)*120+50 + } + + locationsValue = dataObject + jsPlumb.ready(() => { + JSP.init({ + dag: this.dag, + instance: this.instance + }) + // Backfill + JSP.jspBackfill({ + // connects + connects: _.cloneDeep(store.state.dag.connects), + // Node location information + locations: _.cloneDeep(locationsValue), + // Node data + largeJson: _.cloneDeep(store.state.dag.tasks) + }) }) - // Backfill - JSP.jspBackfill({ - // connects - connects: _.cloneDeep(store.state.dag.connects), - // Node location information - locations: _.cloneDeep(store.state.dag.locations), - // Node data - largeJson: _.cloneDeep(store.state.dag.tasks) + } else { + jsPlumb.ready(() => { + JSP.init({ + dag: this.dag, + instance: this.instance + }) + // Backfill + JSP.jspBackfill({ + // connects + connects: _.cloneDeep(store.state.dag.connects), + // Node location information + locations: _.cloneDeep(store.state.dag.locations), + // Node data + largeJson: _.cloneDeep(store.state.dag.tasks) + }) }) - }) + } } /** diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue index 0c8cd2e861..94dc2651be 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue @@ -22,6 +22,7 @@
@@ -65,10 +66,12 @@ v-for="(item,$index) in toolOperList" :class="_operationClass(item)" :id="item.code" + :key="$index" @click="_ckOperation(item,$event)">
+ {}) @@ -513,7 +552,7 @@ }) }, mounted () { - this.init() + this.init(this.arg) }, beforeDestroy () { this.resetParams()