cloud-web/src/views/etl/task/taskInfo.vue

416 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="dashboard-container">
<el-button @click="saveActive" icon="el-icon-position" style="margin-right: 20px;float :right">保存</el-button>
<p>选择节点</p>
<div class="antvBox">
<div class="menu-list">
<div v-for="item in moduleList" :key="item.id"
draggable="true"
@dragend="handleDragEnd($event, item)">
<img :src="item.image" alt="" />
<p>{{ item.name }}</p>
</div>
</div>
<div class="canvas-card">
<div id="container" />
</div>
</div>
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%"
>
<span>
<el-radio-group v-model="labelPosition" size="small">
<el-radio-button label="left">左对齐</el-radio-button>
<el-radio-button label="right">右对齐</el-radio-button>
<el-radio-button label="top">顶部对齐</el-radio-button>
</el-radio-group>
<div style="margin: 20px;"></div>
<el-form :label-position="labelPosition" label-width="80px" :model="tableMsg">
<el-form-item label="任务id">
<el-input v-model="tableMsg.id" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="数据库id">
<el-input v-model="tableMsg.databaseId" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="数据表">
<el-cascader
v-model="tableMsg.tableName"
:options="tables"
:props="{ expandTrigger: 'hover',value:'name',label:'name',children:'tableNames' }"
@change="handleChange"></el-cascader>
</el-form-item>
<el-form-item label="表别名">
<el-input v-model="tableMsg.tableAsField"></el-input>
</el-form-item>
</el-form>
</span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { Graph } from "@antv/x6";
import {extractDataName} from "../../../api/etl/etl";
export default {
name: "antvX6",
data() {
return {
tables:{},
tableMsg:{},
labelPosition: 'right',
dialogVisible:false,
curSelectNode: "",
moduleList: [
{
id: 1,
name: "表1",
image: require("@/assets/img/1.png"),
},
{
id: 8,
name: "表2",
image: require("@/assets/img/2.png"),
},
{
id: 2,
name: "联查",
image: require("@/assets/img/3.png"),
},
{
id: 3,
name: "节点4",
image: require("@/assets/img/4.png"),
},
],
graph: null
};
},
methods: {
handleChange(value) {
console.log(value);
},
getDatabaseMessage(){
this.dialogVisible = true
extractDataName().then(response => {
this.tables = response.data
})
},
//todo 鼠标划过节点在显示连接桩
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);
});
this.graph.on("node:dblclick",() =>{
this.getDatabaseMessage()
})
//todo 节点绑定点击事件
this.graph.on("node:click", ({ e, x, y, node, view }) => {
// 判断是否有选中过节点
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,
},
},
},
]);
}
});
//todo 连线绑定悬浮事件
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; // 保证未悬停的线在下层,不会遮挡悬停的线
}
});
},
// 拖动后松开鼠标触发事件
handleDragEnd(e, item) {
// 可以获取到最后拖动后松开鼠标时的坐标和拖动的节点相关信息
this.addHandleNode(
e.pageX - 500,
e.pageY - 200,
new Date().getTime(),
item.image,
item.name
);
},
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, // 网格大小 10px
visible: true, // 渲染网格背景
args: {
color: "#a0a0a0", // 网格线/点颜色
thickness: 2, // 网格线宽度/网格点大小
},
},
});
this.nodeAddEvent()
},
//添加节点到画布
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,
});
},
//todo 保存画布,并提交
saveActive() {
console.log(this.graph.toJSON(), "graph");
console.log(this.graph.getNodes(), "node");
},
},
//生命周期 - 挂载完成可以访问DOM元素",
mounted() {
this.initGraph()
},
};
</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>