liuchengtu

This commit is contained in:
shijing 2021-09-18 11:34:24 +08:00
parent 30c4006252
commit bbfaa3ed07
9 changed files with 566 additions and 226 deletions

View File

@ -19,6 +19,8 @@
"@riophae/vue-treeselect": "^0.4.0",
"axios": "^0.21.1",
"compression-webpack-plugin": "^5.0.1",
"d3": "^5.14.2",
"dagre-d3": "^0.6.4",
"element-ui": "^2.15.5",
"file-saver": "^2.0.2",
"fuse.js": "^6.4.6",

View File

@ -120,4 +120,12 @@ export function deleteWfTransition(id, data) {
method: 'delete',
data
})
}
}
//工单详情
export function getTickets(query) {
return request({
url: `/wf/ticket/`,
method: 'get',
params:query
})
}

View File

@ -7,7 +7,7 @@
<div class="right-menu">
<template>
<search id="header-search" class="right-menu-item" />
<el-tooltip content="Global Size" effect="dark" placement="bottom">
<el-tooltip content="全局组件大小" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip>
</template>

View File

@ -13,8 +13,8 @@
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
v-for="(child,$index) in item.children"
:key="child.path+$index"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"

View File

@ -242,6 +242,19 @@ export const asyncRoutes = [
meta: { title: '人员信息详情', icon: 'example', perms: ['configuration_manage'] },
hidden: true
},
{
path: 'ticket',
name: 'ticket',
component: () => import('@/views/workflow/ticket'),
meta: { title: '工单列表', icon: 'example', perms: ['ticket_manage'] },
hidden: true
},{
path: 'test',
name: 'test',
component: () => import('@/views/workflow/test'),
meta: { title: '工单', icon: 'example', perms: ['test_manage'] },
hidden: true
},
]
},
{

View File

@ -1,7 +1,7 @@
<template>
<div class="app-container">
<el-card>
<div style="margin-top: 10px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>新增</el-button
@ -10,7 +10,7 @@
</el-card>
<el-card style="margin-top: 10px">
<el-table
:data="customfieldList"
style="width: 100%"
>
@ -40,7 +40,7 @@
width="220px"
>
<template slot-scope="scope">
<el-link
v-if="checkPermission(['customfield_update'])"
@click="handleEdit(scope)"
@ -49,119 +49,68 @@
<el-link
v-if="checkPermission(['customfield_delete'])"
type="danger"
@click="handleDelete(scope)"
@click="handleDeleteCustomfield(scope)"
>删除</el-link
>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑自定义字段' : '新增自定义字段'"
>
:title="dialogType === 'edit' ? '编辑自定义字段' : '新增自定义字段'">
<el-form
ref="Form"
:model="customfield"
label-width="80px"
label-position="right"
:rules="rule1"
>
:rules="rule1">
<el-form-item label="字段标识" prop="field_key">
<el-input v-model="customfield.field_key" placeholder="字段标识" />
</el-form-item>
<el-form-item label="字段名称" prop="field_name">
<el-input v-model="customfield.field_name" placeholder="字段名称" />
<el-input v-model="customfield.field_name" placeholder="字段名称" />
</el-form-item>
<el-form-item label="字段描述" prop="description">
<el-input v-model="customfield.description" placeholder="字段描述" />
<el-form-item label="字段描述" prop="description">
<el-input v-model="customfield.description" placeholder="字段描述" />
</el-form-item>
<el-form-item label="占位符" prop="placeholder">
<el-input v-model="customfield.placeholder" placeholder="占位符" />
<el-form-item label="占位符" prop="placeholder">
<el-input v-model="customfield.placeholder" placeholder="占位符" />
</el-form-item>
<el-form-item label="字段类型" prop="field_type">
<el-select style="width: 100%" v-model="customfield.field_type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-form-item label="字段类型" prop="field_type">
<el-select style="width: 100%" v-model="customfield.field_type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="顺序ID" prop="sort">
<el-input v-model="customfield.sort" type="number" placeholder="顺序" />
<el-form-item label="选项" v-show="customfield.field_type=='select'||customfield.field_type=='selects'">
<el-button @click.prevent="addDomain" style="border: none;">
<i class="el-icon-circle-plus-outline"></i>
<span style="font-size:14px;">添加</span>
</el-button>
<el-row v-for="(domain, $index) in choiceOption" :key=domain+$index style="margin-bottom: 10px">
<el-col :span="20">
<el-input v-model="choiceOption[$index]" auto-complete="off"></el-input>
</el-col>
<el-col :span="3" style="text-align: center" v-if="$index!==0">
<i class="el-icon-remove-outline" @click.prevent="removeDomain($index,'1')" style="color: red;font-size: 16px;"></i>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="默认值" prop="default_value">
<el-input v-model="customfield.default_value" placeholder="默认值" />
<el-form-item label="顺序ID" prop="sort">
<el-input v-model="customfield.sort" type="number" placeholder="顺序" />
</el-form-item>
<el-form-item
label="布尔显示定义"
prop="boolean_field_display"
label-width="120px"
>
<vue-json-editor
v-model="customfield.boolean_field_display"
:showBtns="false"
:mode="'code'"
lang="zh"
@json-change="onJsonChange"
@json-save="onJsonSave"
@has-error="onError"
/>
</el-form-item>
<el-form-item
label="选项"
prop="field_choice"
label-width="120px"
>
<vue-json-editor
v-model="customfield.field_choice"
:showBtns="false"
:mode="'code'"
lang="zh"
@json-change="onJsonChange1"
@json-save="onJsonSave1"
@has-error="onError1"
/>
</el-form-item>
<el-form-item
label="标签"
prop="label"
label-width="120px"
>
<vue-json-editor
v-model="customfield.label"
:showBtns="false"
:mode="'code'"
lang="zh"
@json-change="onJsonChange2"
@json-save="onJsonSave2"
@has-error="onError2"
/>
</el-form-item>
<el-form-item label="模板" prop="field_template">
<el-form-item label="默认值" prop="default_value">
<el-input v-model="customfield.default_value" placeholder="默认值" />
</el-form-item>
<el-form-item label="模板" prop="field_template">
<el-input v-model="customfield.field_template" placeholder="你有一个待办工单:{title}" />
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -185,41 +134,44 @@ export default {
props: ["ID"],
data() {
return {
customfield: defaultcustomfield,
customfield: {
field_key:'',
field_name:'',
placeholder:'',
field_type:'',
sort:'',
default_value:'',
field_template:'',
field_choice:[]
},
view_permission_check:false,
hasJsonFlag:true, // json是否验证通过
hasJsonFlag1:true, // json是否验证通过
hasJsonFlag2:true, // json是否验证通过
hasJsonFlag:true, // json是否验证通过
hasJsonFlag1:true, // json是否验证通过
hasJsonFlag2:true, // json是否验证通过
customfieldList: {
count:0
},
options: [{
value: 'string',
label: '字符串'
label: '文本'
}, {
value: 'int',
label: ''
label: ''
}, {
value: 'float',
label: '浮点型'
}, {
value: 'bool',
label: '布尔'
label: '小数'
}, {
value: 'date',
label: '日期'
}, {
value: 'datetime',
label: '日期时间'
}, {
value: 'radio',
label: '单选框'
}, {
value: 'checkbox',
label: '多选框'
}, {
},{
value: 'select',
label: '下拉列表'
label: '单选'
},{
value: 'selects',
label: '多选'
}, {
value: 'textarea',
label: '文本域'
@ -233,9 +185,10 @@ export default {
value: 'file',
label: '附件'
}],
boolean_field_display:[],
choiceOption:[''],
field_choice:[],
dialogVisible: false,
dialogType: "new",
@ -251,19 +204,27 @@ export default {
this.getList();
},
methods: {
//添加字段选项
addDomain() {
this.choiceOption.push('')
},
//删除字段选项
removeDomain(index){
this.choiceOption.splice(index, 1)
},
checkPermission,
getList() {
getWfCustomfieldList(this.ID).then((response) => {
if (response.data) {
this.customfieldList = response.data;
}
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
@ -283,9 +244,10 @@ export default {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.customfield = Object.assign({}, scope.row); // copy obj
this.choiceOption = scope.row.field_choice;
this.dialogType = "edit";
this.dialogVisible = true;
this.$nextTick(() => {
@ -312,8 +274,8 @@ export default {
console.error(err);
});
},
async confirm(form) {
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
@ -321,6 +283,7 @@ export default {
this.checkJson();
this.checkJson1();
this.checkJson2();
this.customfield.field_choice = this.choiceOption;
updateWfCustomfield(this.customfield.id, this.customfield).then((res) => {
if (res.code >= 200) {
this.getList();
@ -333,7 +296,7 @@ export default {
this.checkJson1();
this.checkJson2();
this.customfield.workflow=this.ID;
this.customfield.field_choice = this.choiceOption;
createWfCustomfield(this.customfield).then((res) => {
if (res.code >= 200) {
this.getList();
@ -347,7 +310,7 @@ export default {
}
});
},
handleDelete(scope) {
handleDeleteCustomfield(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
@ -377,7 +340,7 @@ export default {
// console.log("json错误了value:", value);
this.hasJsonFlag = false
},
// 检查json
checkJson(){
if (this.hasJsonFlag == false){

View File

@ -2,33 +2,31 @@
<div class="app-container">
<el-card>
<div>
<el-input
v-model="listQuery.search"
placeholder="名称"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button
>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置</el-button
>
</div>
<div style="margin-top: 10px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>新增</el-button
>
</div>
<el-input
v-model="listQuery.search"
placeholder="名称"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button
>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置</el-button
>
</div>
<div style="margin-top: 10px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新增</el-button>
</div>
</el-card>
<el-card style="margin-top: 10px">
<el-table
@ -47,15 +45,14 @@
<el-table-column label="描述">
<template slot-scope="scope">{{ scope.row.description }}</template>
</el-table-column>
<el-table-column label="工单查看权限校验">
<template slot-scope="scope">
{{ !!(scope.row.view_permission_check)?'':'' }}
<el-table-column label="工单查看权限校验">
<template slot-scope="scope">
{{ !!(scope.row.view_permission_check)?'':'' }}
</template>
</el-table-column>
<el-table-column width="180" label="创建时间">
<el-table-column width="180" label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
@ -65,19 +62,20 @@
<el-link
v-if="checkPermission(['workflow_update'])"
@click="handlecfgt(scope)"
>配置</el-link
>
>配置</el-link>
<el-link
v-if="checkPermission(['workflow_update'])"
@click="handleEdit(scope)"
>编辑</el-link
>
>编辑</el-link>
<el-link
v-if="checkPermission(['workflow_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link
>
>删除</el-link>
<el-link
type="primary"
@click="handleTicket(scope)"
>查看工单</el-link>
</template>
</el-table-column>
</el-table>
@ -91,20 +89,19 @@
</el-card>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? '编辑设备' : '新增设备'"
>
:title="dialogType === 'edit' ? '编辑工作流' : '新增工作流'">
<el-form
ref="Form"
:model="workflow"
label-width="80px"
label-width="100px"
label-position="right"
:rules="rule1"
>
:rules="rule1">
<el-form-item label="名称" prop="name">
<el-input v-model="workflow.name" placeholder="名称" />
</el-form-item>
<el-form-item label="流水号前缀">
<el-input v-model="workflow.sn_prefix " placeholder="流水号前缀" />
</el-form-item>
<el-form-item label="描述" prop="description">
<el-input
type="textarea"
@ -113,51 +110,25 @@
placeholder="描述"
/>
</el-form-item>
<el-form-item
<el-form-item
label="查看权限校验"
prop="view_permission_check"
label-width="120px"
>
<el-switch v-model="workflow.view_permission_check"></el-switch>
</el-form-item>
<el-form-item
label="限制表达式"
prop="limit_expression"
label-width="120px"
>
<vue-json-editor
v-model="workflow.limit_expression"
:showBtns="false"
:mode="'code'"
lang="zh"
@json-change="onJsonChange"
@json-save="onJsonSave"
@has-error="onError"
/>
<br>
</el-form-item>
<el-form-item
label="展现表单字段"
prop="display_form_str"
label-width="120px"
>
<vue-json-editor
v-model="workflow.display_form_str"
:showBtns="false"
:mode="'code'"
lang="zh"
@json-change="onJsonChange1"
@json-save="onJsonSave1"
@has-error="onError1"
/>
<br>
</el-form-item>
<el-form-item label="标题模板" prop="title_template">
<el-form-item label="展现表单字段">
<el-transfer
v-model="workflow.display_form_str"
:data="choiceOption"
:titles="['未展示字段', '展示字段']"
:props="{ key: 'id', label: 'field_name' }"
/>
</el-form-item>
<el-form-item label="标题模板" prop="title_template">
<el-input v-model="workflow.title_template" placeholder="你有一个待办工单:{title}" />
</el-form-item>
<el-form-item label="内容模板" prop="content_template">
<el-form-item label="内容模板" prop="content_template">
<el-input v-model="workflow.content_template" placeholder="标题:{title}, 创建时间:{create_time}" />
</el-form-item>
</el-form>
@ -169,30 +140,40 @@
</div>
</template>
<script>
import { getWorkflowList, createWorkflow,updateWorkflow,deleteWorkflow } from "@/api/workflow";
import checkPermission from "@/utils/permission";
import vueJsonEditor from 'vue-json-editor'
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import { getWorkflowList, createWorkflow,updateWorkflow,deleteWorkflow,getWfCustomfieldList,getWfStateList } from "@/api/workflow";
import checkPermission from "@/utils/permission";
// import vueJsonEditor from 'vue-json-editor'
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultworkflow = {
name: "",
number: "",
};
export default {
components: { Pagination,vueJsonEditor },
components: { Pagination },
data() {
return {
workflow: defaultworkflow,
// workflow: defaultworkflow,
workflow:{
name:'',
sn_prefix:'',
description:'',
view_permission_check:'',
display_form_str:'',
title_template:'',
content_template:'',
},
view_permission_check:false,
hasJsonFlag:true, // json是否验证通过
hasJsonFlag1:true, // json是否验证通过
workflowList: {
count: 0,
},
listQuery: {
page: 1,
page_size: 20,
},
choiceOption:[],
display_form_str:[],
limit_expression:[],
listLoading: true,
@ -211,7 +192,6 @@ export default {
},
methods: {
checkPermission,
getList() {
this.listLoading = true;
getWorkflowList(this.listQuery).then((response) => {
@ -221,8 +201,6 @@ export default {
this.listLoading = false;
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
@ -242,7 +220,6 @@ export default {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.workflow = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
@ -250,12 +227,17 @@ export default {
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
getWfCustomfieldList(scope.row.id).then((response) => {
if (response.data) {
this.choiceOption = response.data;
}
});
},
handlecfgt(scope)
{
this.$router.push({name:"configuration",params:{workflow:scope.row.id}})
}
,
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
@ -271,13 +253,18 @@ export default {
console.error(err);
});
},
handleTicket(scope){
this.$router.push({name:"ticket",params:{workflow:scope.row.id}})
},
async confirm(form) {
debugger;
console.log(this.workflow.display_form_str)
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
this.checkJson();
this.checkJson();
this.checkJson2();
updateWorkflow(this.workflow.id, this.workflow).then((res) => {
if (res.code >= 200) {
@ -289,7 +276,6 @@ export default {
} else {
this.checkJson();
this.checkJson2();
createWorkflow(this.workflow).then((res) => {
if (res.code >= 200) {
this.getList();
@ -304,7 +290,6 @@ export default {
});
},
onJsonChange (value) {
// console.log('更改value:', value);
// 实时保存
@ -361,8 +346,6 @@ export default {
return true
}
},
},
};
</script>

View File

@ -0,0 +1,133 @@
<template>
<div id="container" style="border: 1px solid #000000;">
<svg width="900" height="1500">
<g />
<rect />
</svg>
</div>
</template>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
import dagreD3 from "dagre-d3";
import * as d3 from "d3";
export default {
data() {
return {
nodes: [
{
id: "2",
label: "开始",
shape: "rect"
},
{
id: "3",
label: "部门领导审批",
shape: "diamond"
},
{
id: "4",
label: "综合办公室审批",
shape: "diamond"
},
{
id: "5",
label: "结束",
shape: "rect"
},
],
edges: [
{
source: "2",
target: "3",
label: ""
},
{
source: "3",
target: "4",
label: "同意"
},
{
source: "4",
target: "5",
label: "同意"
},
]
};
},
mounted() {
//获取D3
var g = new dagreD3.graphlib.Graph().setGraph({
align: 'DL',
nodesep: 100,
edgesep: 100,
ranksep: 50,
marginx: 50,
marginy: 100,
});
console.log(g);
// 添加节点
this.nodes.forEach((item) => {
g.setNode(item.id, {
// 节点标签
label: item.label,
// 节点形状
shape: item.shape,
toolText: item.label,
//节点样式
style: "fill:#fff;stroke:#000",
// 节点样式
labelStyle: "fill:#000;",
width: 83,
height: 40,
rx :5,
ry :5
});
});
// 链接关系
this.edges.forEach(item => {
g.setEdge(item.source, item.target, {
// 边标签
label: item.label,
// 边样式
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px" // 根据后台数据来改变连线的颜色
});
});
g.nodes().forEach(function (v) {
console.log("Node " + v + ": " + JSON.stringify(g.node(v)));
});
g.edges().forEach(function (e) {
console.log("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(g.edge(e)));
});
// 创建渲染器
let render = new dagreD3.render();
// 选择 svg 并添加一个g元素作为绘图容器.
let svg = d3.select('svg');
let svgGroup = svg.select('g');
// 在绘图容器上运行渲染器生成流程图.
render(d3.select("svg g"), g);
}
};
</script>
<style scoped>
svg {
}
.node rect {
stroke: #606266;
fill: #fff;
}
.edgePath path {
stroke: #606266;
fill: #333;
stroke-width: 1.5px;
}
#__SVG_SPRITE_NODE__{
position: absolute!important;
width: 689px!important;
height: 800px!important;
left: 300px!important;
top: 331px!important;
}
</style>

View File

@ -0,0 +1,238 @@
<template>
<div class="app-container">
<el-card style="margin-top: 10px">
<el-table v-loading="listLoading" :data="tickets" border fit stripe highlight-current-row max-height="600">
<el-table-column type="index" width="50" />
<el-table-column label="工单标题">
<template slot-scope="scope">{{ scope.row.title }}</template>
</el-table-column>
<el-table-column label="当前状态">
<template slot-scope="scope">{{ scope.row.act_state }}</template>
</el-table-column>
<el-table-column width="180" label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column align="center" label="操作" width="220px">
<template slot-scope="scope">
<el-link v-if="stateSteps==scope.row.act_state" type="danger" @click="handlePicture(scope)">查看流程图</el-link>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="pageForm.page"
:limit.sync="pageForm.page_size"
@pagination="getList"
/>
</el-card>
<div class="svgMark" v-if="dialogVisible" @click="closeMark">
<div class="svgWrapper">
<div class="svgItem">工单流程图<i class="el-dialog__close el-icon el-icon-close" @click="closeMark"></i></div>
<svg height=600 id="svg">
<g id="svgG"/>
<rect/>
</svg>
</div>
</div>
</div>
</template>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
import {getWfStateList,getTickets } from "@/api/workflow";
import Pagination from "@/components/Pagination";
import dagreD3 from 'dagre-d3'
import * as d3 from 'd3'
export default {
name: "ticket",
components: { Pagination },
data(){
return{
total:0,
pageForm:{
page:1,
page_size:20,
workflow:0,
},
workflow:0,
stateSteps:0,
keyword:'',
tickets:[],
dialogVisible:false,
listLoading:false,
nodes: [],
tooltip:null,
edges: []
}
},
created(){
this.workflow = this.$route.params.workflow;
let workflow = localStorage.getItem('workflow');
if(this.workflow){
this.pageForm.workflow = parseInt(this.workflow);
if(workflow){
localStorage.removeItem('workflow');
localStorage.setItem('workflow',this.$route.params.workflow)
}else{
localStorage.setItem('workflow',this.$route.params.workflow)
}
}else{
this.workflow =workflow ;
this.pageForm.workflow =workflow ;
}
this.getList();
this.getStates();
},
methods:{
getList(){
getTickets( this.pageForm).then((res)=>{
if(res.data.results){
this.tickets = res.data.results;
}
})
},
getStates(){
getWfStateList(this.workflow).then((response) => {
if (response.data) {
let nodes = [];
let res = response.data;
this.stateSteps = res.length;
for(let i=0;i<res.length;i++){
let obj = new Object();
obj.id = res[i].id;
obj.label = res[i].name;
obj.shape = res[i].type===0? 'diamond':'rect';
nodes.push(obj)
}
this.nodes = nodes;
console.log(nodes)
this.getEdges(nodes);
}
});
},
getEdges(nodes){
let edge = [];
for(let i=1;i<nodes.length;i++){
let obj = new Object();
obj.source = nodes[i-1].id;
obj.target = nodes[i].id;
obj.label = i>1?'同意':'';
edge.push(obj);
}
this.edges = edge;
console.log(edge)
},
handleFilter(){},
handlePicture(){
// this.$router.push({name:"test"})
this.dialogVisible = true;
//获取D3
this.$nextTick(()=>{
var g = new dagreD3.graphlib.Graph().setGraph({
align: 'DL',
nodesep: 100,
edgesep: 100,
ranksep: 50,
marginx: 50,
marginy: 50,
});
console.log(g);
// 添加节点
this.nodes.forEach((item) => {
g.setNode(item.id, {
// 节点标签
label: item.label,
// 节点形状
shape: item.shape,
toolText: item.label,
//节点样式
style: "fill:#fff;stroke:#000",
// 节点样式
labelStyle: "fill:#000;",
width: 83,
height: 40,
rx :5,
ry :5
});
});
// 链接关系
this.edges.forEach(item => {
g.setEdge(item.source, item.target, {
// 边标签
label: item.label,
// 边样式
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px" // 根据后台数据来改变连线的颜色
});
});
g.nodes().forEach(function (v) {
console.log("Node " + v + ": " + JSON.stringify(g.node(v)));
});
g.edges().forEach(function (e) {
console.log("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(g.edge(e)));
});
// 创建渲染器
let render = new dagreD3.render();
// 选择 svg 并添加一个g元素作为绘图容器.
let svg = d3.select('svg');
let svgGroup = svg.select('g');
// 在绘图容器上运行渲染器生成流程图.
render(d3.select("svg g"), g);
})
},
closeMark(){
this.dialogVisible = false;
},
},
mounted() {
}
}
</script>
<style scoped>
.svgMark{
width: 100%;
height: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: auto;
margin: 0;
z-index: 2000;
background: rgba(0,0,0,.3);
}
.svgWrapper{
background: #fff;
width: 800px;
margin: 10vh auto 0;
text-align: center;
border-radius: 2px;
}
.svgItem{
padding: 20px 40px 0 ;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
font-size: 18px;
display: flex;
justify-content: space-between;
}
svg {
font-size: 14px;
}
.node rect {
stroke: #606266;
fill: #fff;
}
.edgePath path {
stroke: #606266;
fill: #333;
stroke-width: 1.5px;
}
.el-icon-close{
cursor: pointer;
}
</style>