antv-X6-Vue3总结02-普通节点配置
<!--* 节点与边的交换--><template><div id="containered" ref="containered" /></template><script lang="ts" setup>/*eslint-disable */import { ref, computed, onMounted } from 'vue'im
·
部分源代码:https://gitee.com/eadela/x6-example.git
<!--
* 节点与边的交换
-->
<template>
<div id="containered" ref="containered" />
</template>
<script lang="ts" setup>
/*eslint-disable */
import { ref, computed, onMounted } from 'vue'
import { Graph, Shape } from '@antv/x6';
const graph = ref<any>({}) // 流程图
const containered = ref<HTMLElement>() // 流程图挂载dom节点
const init = () => {
graph.value = new Graph({
container: containered.value,
width: 800,
height: 600,
background: {
color: '#fffbe6', // 设置画布背景颜色
},
grid: {
size: 10, // 网格大小 10px
visible: true, // 渲染网格背景
},
snapline: { // 对齐线
enabled: true,
sharp: true, // 是否显示截断的对齐线-对齐线变短
},
selecting: { // 点选/框选,默认禁用。
enabled: true,
// rubberband: true, // 框选
// 是否显示节点的选择框,默认为 false,建议使用下面的样式定制方法去定制自己的选择框样式。
// showNodeSelectionBox: true // 节点的选择框
},
keyboard: { // 键盘事件可用于绑定快捷键
enabled: true
},
// 开启撤销/重做
history: {
enabled: true,
ignoreChange: true
},
// 剪切板用于复制/粘贴节点和边,并支持跨画布的复制/粘贴,创建画布时通过以下配置启用。
clipboard: {
enabled: true
// useLocalStorage: true // 保存到 localStorage
},
// panning: true, // 普通画布(未开启 scroller 模式)通过开启 panning 选项来支持拖拽平移。
// 使画布具备滚动、平移、居中、缩放等能力
scroller: {
enabled: true,
pageVisible: false, // 是否分页,默认为 false。
pageBreak: false, // 是否显示分页符,默认为 false。
pannable: true // 启用画布平移
},
mousewheel: { // 鼠标滚轮缩放
enabled: true,
// 是否为全局事件,设置为 true 时滚轮事件绑定在 document 上,否则绑定在画布容器上。默认为 false。
global: true,
modifiers: ['ctrl', 'meta']
},
highlighting: {
// 连线过程中,节点可以被链接时被使用
// nodeAvailable: {},
// 拖动节点进行嵌入操作过程中,节点可以被嵌入时被使用
embedding: {
name: 'stroke',
args: {
attrs: {
fill: '#fff',
stroke: '#47C769',
},
},
},
// 连线过程中,链接桩可以被链接时被使用
magnetAvailable: { // 高亮
name: 'stroke',
args: {
attrs: {
fill: '#fff',
stroke: '#47C769',
},
},
},
// 连线过程中,自动吸附到链接桩时被使用
magnetAdsorbed: {
name: 'stroke',
args: {
attrs: {
fill: '#fff',
stroke: '#31d0c6',
},
},
},
},
// 连线规则
connecting: {
snap: true, // 当 snap 设置为 true 时连线的过程中距离节点或者连接桩 50px 时会触发自动吸附
allowBlank: false, // 是否允许连接到画布空白位置的点,默认为 true
allowLoop: false, // 是否允许创建循环连线,即边的起始节点和终止节点为同一节点,默认为 true
allowMulti: false, // 当设置为 false 时,在起始和终止节点之间只允许创建一条边
highlight: true, // 拖动边时,是否高亮显示所有可用的连接桩或节点,默认值为 false。
sourceAnchor: { // 当连接到节点时,通过 sourceAnchor 来指定源节点的锚点。
name: 'center'
},
targetAnchor: 'center', // 当连接到节点时,通过 targetAnchor 来指定目标节点的锚点。
connector: 'rounded', // 连接器将起点、路由返回的点、终点加工为 元素的 d 属性,决定了边渲染到画布后的样式,默认值为 normal。
connectionPoint: 'boundary', // 指定连接点,默认值为 boundary。
router: { // 实体关系路由,由 Z 字形的斜角线段组成。
name: 'er',
args: {
direction: 'T',
},
},
// router: 'manhattan',
// connector: {
// name: 'rounded',
// args: {
// radius: 8
// }
// },
// anchor: 'top',
// sourceAnchor: 'bottom',
// connectionPoint: 'anchor',
// sourceConnectionPoint: 'anchor',
// allowBlank: false,
// snap: {
// radius: 20
// },
// 点击 magnet 时 根据 validateMagnet 返回值来判断是否新增边,
// 触发时机是 magnet 被按下,如果返回 false,则没有任何反应,
// 如果返回 true,会在当前 magnet 创建一条新的边。
validateMagnet({ magnet, cell }) {
// 表示被点击的链接桩
// console.log('magnet', e, magnet, view, cell);
// if (magnet.getAttribute('port-group') === 'in') { //前置节点不能作为起点
// return false
// }
return true
},
createEdge() { // 连接的过程中创建新的边
return new Shape.Edge({
attrs: {
line: {
stroke: '#136fff',
strokeWidth: 1,
targetMarker: {
name: 'classic',
size: 7
}
}
}
})
},
// 在移动边的时候判断连接是否有效,
// 如果返回 false,当鼠标放开的时候,不会连接到当前元素,
// 否则会连接到当前元素。
// 可以连接的节点,链接桩会变色
validateConnection({ sourceMagnet, targetMagnet, sourceCell, targetCell }: any) {
// 只能从输出链接桩创建连接
if (!sourceMagnet || sourceMagnet.getAttribute('port-group') === 'in') {
return false
}
// 只能连接到输入链接桩
if (!targetMagnet || targetMagnet.getAttribute('port-group') !== 'in') {
return false
}
return true
},
// 当停止拖动边的时候根据 validateEdge 返回值来判断边是否生效,如果返回 false, 该边会被清除。
validateEdge({ edge }) {
const { source, target } = edge
return true
}
},
});
graph.value.on('cell:mouseenter', (args: { cell:any }) => {
if (args.cell.isNode()) {
args.cell.addTools([
{
name: 'boundary',
args: {
attrs: {
fill: '#7c68fc',
stroke: '#333',
'stroke-width': 1,
'fill-opacity': 0.2,
},
},
},
{
name: 'button-remove',
args: {
x: 0,
y: 0,
offset: { x: 10, y: 10 },
},
},
])
} else {
args.cell.addTools([
{ name: 'vertices' },
{
name: 'button-remove',
args: { distance: 20 },
}])
}
})
graph.value.on('cell:mouseleave', (args: { cell:any }) => {
args.cell.removeTools()
})
const node1 = new Shape.Rect({
id: 'node1',
// zIndex: 2,
shape:'image-embedded',
x: 40,
y: 40,
width: 64,
height: 64,
markup: [
{
tagName: 'rect', // 节点框
selector: 'body',
},
{
tagName: 'image', // 节点图片
selector: 'image',
},
{
tagName: 'text', // 节点内容
selector: 'label',
},
{
tagName: 'g', // 节点悬浮窗内容
selector: 'tipGroup',
attrs: {
'pointer-events': 'visiblePainted', // 不允许穿透
},
children: [
{
tagName: 'path', // 节点悬浮窗边框
selector: 'tipPath',
},
{
tagName: 'text', // 节点悬浮窗内容
selector: 'tipText',
},
{
tagName: 'text', // 节点悬浮窗编辑按钮
selector: 'tipEditBtn',
},
{
tagName: 'text', // 节点悬浮窗删除按钮
selector: 'tipCancalBtn',
},
],
},
],
attrs: {
body: {
fill: '#fff', // 背景填充白色
stroke: '#136fff', // 边颜色
strokeWidth: 1,
rx: 5, // 弧度
ry: 5,
},
image: {
x: 22,
y: 11,
width: '22',
height: '22',
href: require('@/assets/images/shape/abTest.png'),
textAnchor: 'middle',
textVerticalAnchor: 'top',
},
label: {
refX: 0.5,
refY: '100%',
refY2: -11,
text: '节点名称',
fill: '#333',
fontSize: '12px',
textAnchor: 'middle',
textVerticalAnchor: 'bottom',
},
tipGroup: {
refX: '120%',
refY: '50%',
display: 'none', // block none
},
tipPath: {
d: 'M 0 0 5 5 5 25 150 25 150 -25 5-25 5 -5 Z',
fill: 'rgba(255,255,255,0.7)',
stroke: '#136fff',
'stroke-width': 1,
event: 'node:collapse',
},
tipText: {
// x: 0,
// y: 0,
refX: '120%',
refY: '3%',
fill: '#595959',
text: '提示信息',
fontSize: '12px',
fontFamily: 'Source Han Sans CN',
fontWeight: 400,
},
tipEditBtn: {
// fill: '#2A81EA',
// refY: '15%',
// text: '编辑',
// fontSize: '12px',
// cursor: 'pointer',
// event: 'node:dblclick',
},
tipCancalBtn: {
// fill: '#2A81EA',
// refX: '100%',
// refY: '15%',
// text: '取消',
// fontSize: '12px',
// cursor: 'pointer',
// event: 'node:cancleTipInfo',
},
},
// 连接桩
ports: {
items: [
{
group: 'in',
args: {
x: 32,
y: 4,
},
},
{
group: 'out',
args: {
x: 32,
y: 60,
},
}
],
groups: {
in: {
// 输入桩
position: {
name: 'absolute',
},
attrs: {
circle: {
magnet: 'passive',
r: 5,
stroke: '#136fff',
fill: '#fff',
strokeWidth: 1,
visibility: 'visible' // hidden visible
},
},
},
out: {
// 输出桩
position: {
name: 'absolute',
},
markup: [
// {
// tagName: 'rect', // 输出桩 实际可以识别范围 包含显示范围
// selector: 'body',
// },
{
tagName: 'circle', // 输出桩 实际显示范围
selector: 'circle',
},
],
attrs: {
body: {
refX: -31,
refY: -7,
width: 62,
height: 15,
magnet: true,
strokeWidth: 1,
stroke: '#136fff',
fill: 'rgba(255, 55, 255, 0.6)',
rx: 5, // 弧度
ry: 5,
},
circle: {
magnet: true,
r: 5,
fill: '#fff',
stroke: '#136fff',
strokeWidth: 1,
visibility: 'visible'
},
},
},
},
},
// tools: [
// { name: 'boundary' },
// {
// name: 'button-remove', // 工具名称
// args: { x: 10, y: 10 }, // 工具对应的参数
// },
// ],
})
const node2 = new Shape.Rect({
id: 'node2',
// zIndex: 2,
shape:'image-embedded',
x: 140,
y: 40,
width: 64,
height: 64,
markup: [
{
tagName: 'rect', // 节点框
selector: 'body',
},
{
tagName: 'image', // 节点图片
selector: 'image',
},
{
tagName: 'text', // 节点内容
selector: 'label',
},
{
tagName: 'g', // 节点悬浮窗内容
selector: 'tipGroup',
attrs: {
'pointer-events': 'visiblePainted', // 不允许穿透
},
children: [
{
tagName: 'path', // 节点悬浮窗边框
selector: 'tipPath',
},
{
tagName: 'text', // 节点悬浮窗内容
selector: 'tipText',
},
{
tagName: 'text', // 节点悬浮窗编辑按钮
selector: 'tipEditBtn',
},
{
tagName: 'text', // 节点悬浮窗删除按钮
selector: 'tipCancalBtn',
},
],
},
],
attrs: {
body: {
fill: '#fff', // 背景填充白色
stroke: '#136fff', // 边颜色
strokeWidth: 1,
rx: 5, // 弧度
ry: 5,
},
image: {
x: 22,
y: 11,
width: '22',
height: '22',
href: require('@/assets/images/shape/abTest.png'),
textAnchor: 'middle',
textVerticalAnchor: 'top',
},
label: {
refX: 0.5,
refY: '100%',
refY2: -11,
text: '节点名称',
fill: '#333',
fontSize: '12px',
textAnchor: 'middle',
textVerticalAnchor: 'bottom',
},
tipGroup: {
refX: '120%',
refY: '50%',
display: 'none', // block none
},
tipPath: {
d: 'M 0 0 5 5 5 25 150 25 150 -25 5-25 5 -5 Z',
fill: 'rgba(255,255,255,0.7)',
stroke: '#136fff',
'stroke-width': 1,
event: 'node:collapse',
},
tipText: {
// x: 0,
// y: 0,
refX: '120%',
refY: '3%',
fill: '#595959',
text: '提示信息',
fontSize: '12px',
fontFamily: 'Source Han Sans CN',
fontWeight: 400,
},
tipEditBtn: {
// fill: '#2A81EA',
// refY: '15%',
// text: '编辑',
// fontSize: '12px',
// cursor: 'pointer',
// event: 'node:dblclick',
},
tipCancalBtn: {
// fill: '#2A81EA',
// refX: '100%',
// refY: '15%',
// text: '取消',
// fontSize: '12px',
// cursor: 'pointer',
// event: 'node:cancleTipInfo',
},
},
// 连接桩
ports: {
items: [
{
group: 'in',
args: {
x: 32,
y: 4,
},
},
{
group: 'out',
args: {
x: 32,
y: 60,
},
}
],
groups: {
in: {
// 输入桩
position: {
name: 'absolute',
},
attrs: {
circle: {
magnet: 'passive',
r: 5,
stroke: '#136fff',
fill: '#fff',
strokeWidth: 1,
visibility: 'visible' // hidden visible
},
},
},
out: {
// 输出桩
position: {
name: 'absolute',
},
markup: [
{
tagName: 'rect', // 输出桩 实际可以识别范围 包含显示范围
selector: 'body',
},
{
tagName: 'circle', // 输出桩 实际显示范围
selector: 'circle',
},
],
attrs: {
body: {
refX: -31,
refY: -7,
width: 62,
height: 15,
magnet: true,
strokeWidth: 0,
stroke: '#136fff',
fill: 'rgba(255, 255, 255, 0)',
rx: 5, // 弧度
ry: 5,
},
circle: {
magnet: true,
r: 5,
fill: '#fff',
stroke: '#136fff',
strokeWidth: 1,
visibility: 'visible'
},
},
},
},
},
// tools: [
// { name: 'boundary' },
// {
// name: 'button-remove', // 工具名称
// args: { x: 10, y: 10 }, // 工具对应的参数
// },
// ],
})
const node3= new Shape.Rect({
id: 'node3',
// zIndex: 2,
shape:'image-embedded',
x: 40,
y: 240,
width: 64,
height: 64,
markup: [
{
tagName: 'rect', // 节点框
selector: 'body',
},
{
tagName: 'image', // 节点图片
selector: 'image',
},
{
tagName: 'text', // 节点内容
selector: 'label',
},
{
tagName: 'g', // 节点悬浮窗内容
selector: 'tipGroup',
attrs: {
'pointer-events': 'visiblePainted', // 不允许穿透
},
children: [
{
tagName: 'path', // 节点悬浮窗边框
selector: 'tipPath',
},
{
tagName: 'text', // 节点悬浮窗内容
selector: 'tipText',
},
{
tagName: 'text', // 节点悬浮窗编辑按钮
selector: 'tipEditBtn',
},
{
tagName: 'text', // 节点悬浮窗删除按钮
selector: 'tipCancalBtn',
},
],
},
],
attrs: {
body: {
fill: '#fff', // 背景填充白色
stroke: '#136fff', // 边颜色
strokeWidth: 1,
rx: 5, // 弧度
ry: 5,
},
image: {
x: 22,
y: 11,
width: '22',
height: '22',
href: require('@/assets/images/shape/abTest.png'),
textAnchor: 'middle',
textVerticalAnchor: 'top',
},
label: {
refX: 0.5,
refY: '100%',
refY2: -11,
text: '节点名称',
fill: '#333',
fontSize: '12px',
textAnchor: 'middle',
textVerticalAnchor: 'bottom',
},
tipGroup: {
refX: '120%',
refY: '50%',
display: 'none', // block none
},
tipPath: {
d: 'M 0 0 5 5 5 25 150 25 150 -25 5-25 5 -5 Z',
fill: 'rgba(255,255,255,0.7)',
stroke: '#136fff',
'stroke-width': 1,
event: 'node:collapse',
},
tipText: {
// x: 0,
// y: 0,
refX: '120%',
refY: '3%',
fill: '#595959',
text: '提示信息',
fontSize: '12px',
fontFamily: 'Source Han Sans CN',
fontWeight: 400,
},
tipEditBtn: {
// fill: '#2A81EA',
// refY: '15%',
// text: '编辑',
// fontSize: '12px',
// cursor: 'pointer',
// event: 'node:dblclick',
},
tipCancalBtn: {
// fill: '#2A81EA',
// refX: '100%',
// refY: '15%',
// text: '取消',
// fontSize: '12px',
// cursor: 'pointer',
// event: 'node:cancleTipInfo',
},
},
// 连接桩
ports: {
items: [
{
group: 'in',
args: {
x: 32,
y: 4,
},
},
{
group: 'out',
args: {
x: 32,
y: 60,
},
}
],
groups: {
in: {
// 输入桩
position: {
name: 'absolute',
},
attrs: {
circle: {
magnet: 'passive',
r: 5,
stroke: '#136fff',
fill: '#fff',
strokeWidth: 1,
visibility: 'visible' // hidden visible
},
},
},
out: {
// 输出桩
position: {
name: 'absolute',
},
markup: [
{
tagName: 'rect', // 输出桩 实际可以识别范围 包含显示范围
selector: 'body',
},
{
tagName: 'circle', // 输出桩 实际显示范围
selector: 'circle',
},
],
attrs: {
body: {
refX: -31,
refY: -7,
width: 62,
height: 15,
magnet: true,
strokeWidth: 0,
stroke: '#136fff',
fill: 'rgba(255, 255, 255, 0)',
rx: 5, // 弧度
ry: 5,
},
circle: {
magnet: true,
r: 5,
fill: '#fff',
stroke: '#136fff',
strokeWidth: 1,
visibility: 'visible'
},
},
},
},
},
// tools: [
// { name: 'boundary' },
// {
// name: 'button-remove', // 工具名称
// args: { x: 10, y: 10 }, // 工具对应的参数
// },
// ],
})
const circle2 = new Shape.Ellipse({
shape: 'ellipse',
x: 240,
y: 340,
width: 64,
height: 64,
zIndex: 2,
markup: [
{
tagName: 'ellipse', // 节点框
selector: 'body',
},
{
tagName: 'path',
selector: 'cross',
attrs: {
fill: 'none',
'pointer-events': 'none',
},
},
],
attrs: {
body: {
fill: '#fff', // 背景填充白色
stroke: '#136fff', // 边颜色
'stroke-dasharray': '3',
strokeWidth: 1,
},
cross: {
d: 'M 1 5 9 5 M 5 1 5 9',
strokeWidth: 1.6,
refX: 27,
refY: 27,
stroke: '#136fff',
},
},
// 连接桩
ports: {
items: [
{
group: 'in',
args: {
x: 32,
y: 4,
},
},
],
groups: {
in: {
// 输入桩
position: {
name: 'absolute',
},
markup: [
{
tagName: 'circle', // 输出桩 实际显示范围
selector: 'circle',
},
],
attrs: {
circle: {
magnet: 'passive',
r: 5,
fill: 'rgba(255, 255, 255, 0)',
stroke: '#136fff',
strokeWidth: 1,
},
},
},
},
}
})
const edge = new Shape.Edge({
id: 'edge1',
source: node1,
target: circle2,
zIndex: 1,
attrs: {
line: {
stroke: '#136fff',
strokeWidth: 1,
targetMarker: {
name: 'classic',
size: 7
}
}
}
})
graph.value.addNode(node1)
graph.value.addNode(node2)
graph.value.addNode(node3)
graph.value.addNode(circle2)
graph.value.addEdge(edge)
}
onMounted(() => {
init()
})
</script>
更多推荐
已为社区贡献11条内容
所有评论(0)