Vue draws drag flow diagrams using ANTV X6
The installation
# npm
$ npm install @antv/x6 --save
# yarn
$ yarn add @antv/x6
Copy the code
use
Create a container
<! - canvas - >
<div class="graph" ref="graph"></div>
<! -- Toolbar -->
<div class="stencil" ref="stencil"></div>
Copy the code
Create instance Canvas
/ / introduction
import { Graph, Addon, Shape } from '@antv/x6';
// Create an instance
const graph = new Graph({
container: this.$refs.graph, // Canvas container
// grid: true, // grid
width: 770.height: 590.mousewheel: {
enabled: true.zoomAtMousePosition: true.modifiers: 'ctrl'.minScale: 0.5.maxScale: 3,},// Mouse wheel zoom
resizing: true.// Scale the node
selecting: {
enabled: true.rubberband: true.showNodeSelectionBox: true,},// Click/box to select
connecting: {
router: {
name: 'manhattan'.args: {
padding: 1,}},connector: {
name: 'rounded'.args: {
radius: 8,}},anchor: 'center'.connectionPoint: 'anchor'.allowBlank: false.snap: {
radius: 20,},createEdge() {
return new Shape.Edge({
attrs: {
line: {
stroke: '#9ED4FF'.strokeWidth: 2.targetMarker: {
name: 'block'.width: 12.height: 8,}}},zIndex: 0}); },validateConnection({ targetMagnet }) {
return!!!!! targetMagnet; }},// Connect options
highlighting: {
magnetAdsorbed: {
name: 'stroke'.args: {
attrs: {
fill: '#5F95FF'.stroke: '#5F95FF',},},},},// Highlight options.
snapline: true./ / alignment lines
keyboard: true.// Keyboard shortcuts
clipboard: true./ / shear plate
});
Copy the code
Create a toolbar instance
// Toolbar const stencil = new Addon.Stencil({title: 'flow chart ', // title target: graph, // stencilGraphWidth: 600, stencilGraphHeight: 500, collapsable: false, // Collapsable groups: [{title: 'base chart ', name: 'group1',},], // provide group layoutOptions: {columns: 1, columnWidth: 80, rowHeight: 50,}, // to automatically layout nodes}); / / will this $refs. The font. The appendChild (font. The container);Copy the code
Connection point configuration
// Join point four join points
const ports = {
groups: {
top: {
position: 'top'.attrs: {
circle: {
r: 4.magnet: true.stroke: '#5F95FF'.strokeWidth: 1.fill: '#fff'.style: {
visibility: 'hidden',},},},},right: {
position: 'right'.attrs: {
circle: {
r: 4.magnet: true.stroke: '#5F95FF'.strokeWidth: 1.fill: '#fff'.style: {
visibility: 'hidden',},},},},bottom: {
position: 'bottom'.attrs: {
circle: {
r: 4.magnet: true.stroke: '#5F95FF'.strokeWidth: 1.fill: '#fff'.style: {
visibility: 'hidden',},},},},left: {
position: 'left'.attrs: {
circle: {
r: 4.magnet: true.stroke: '#5F95FF'.strokeWidth: 1.fill: '#fff'.style: {
visibility: 'hidden',},},},},},items: [{group: 'top'}, {group: 'right'}, {group: 'bottom'}, {group: 'left',}]};Copy the code
Custom node
// Customize the node
Graph.registerNode(
'custom-rect',
{
inherit: 'rect'.width: 66.height: 36.attrs: {
body: {
strokeWidth: 1.stroke: '#5F95FF'.fill: '#EFF4FF',},text: {
fontSize: 12.fill: '# 262626',}},ports: { ...ports },
},
true
);
Graph.registerNode(
'custom-polygon',
{
inherit: 'polygon'.width: 66.height: 36.attrs: {
body: {
strokeWidth: 1.stroke: '#5F95FF'.fill: '#EFF4FF',},text: {
fontSize: 12.fill: '# 262626',}},ports: {
...ports,
items: [{group: 'top'}, {group: 'bottom',},],},},true
);
Graph.registerNode(
'custom-circle',
{
inherit: 'circle'.width: 45.height: 45.attrs: {
body: {
strokeWidth: 1.stroke: '#5F95FF'.fill: '#EFF4FF',},text: {
fontSize: 12.fill: '# 262626',}},ports: { ...ports },
},
true
);
const r1 = graph.createNode({
shape: 'custom-rect'.attrs: {
text: {
fontSize: 18,},body: {
rx: 40.ry: 26,}}});const r2 = graph.createNode({
shape: 'custom-rect'.attrs: {
text: {
fontSize: 18,}}});const r3 = graph.createNode({
shape: 'custom-rect'.attrs: {
text: {
fontSize: 18,},body: {
rx: 6.ry: 6,}}});const r4 = graph.createNode({
shape: 'custom-polygon'.attrs: {
body: {
refPoints: '0, 10, 0 to 20, 10, 10, 20',},text: {
fontSize: 18,}}}); stencil.load([r1, r2, r3, r4],'group1');
Copy the code
Shortcut keys and event triggering
// Shortcuts and events
// Copy and paste
graph.bindKey(['meta+c'.'ctrl+c'].() = > {
const cells = graph.getSelectedCells();
if (cells.length) {
graph.copy(cells);
}
return false;
});
graph.bindKey(['meta+x'.'ctrl+x'].() = > {
const cells = graph.getSelectedCells();
if (cells.length) {
graph.cut(cells);
}
return false;
});
graph.bindKey(['meta+v'.'ctrl+v'].() = > {
if(! graph.isClipboardEmpty()) {const cells = graph.paste({ offset: 32 });
graph.cleanSelection();
graph.select(cells);
}
return false;
});
// Control connection pile show/hide
var showPorts = function (ports, show) {
for (var i = 0, len = ports.length; i < len; i = i + 1) {
ports[i].style.visibility = show ? 'visible' : 'hidden'; }};/ / touch
graph.on('node:mouseenter'.({ node }) = > {
// Displays the node delete button
node.addTools({
name: 'button-remove'.args: {
x: '100%'.y: 0.offset: { x: -10.y: 10,}}});var container = this.$refs.graph;
var ports = container.querySelectorAll('.x6-port-body');
showPorts(ports, true);
});
graph.on('node:mouseleave'.({ node }) = > {
// Remove the node delete button
node.removeTools();
var container = this.$refs.graph;
var ports = container.querySelectorAll('.x6-port-body');
showPorts(ports, false);
});
// Text input
graph.on('cell:dblclick'.({ cell, e }) = > {
const isNode = cell.isNode();
const name = cell.isNode() ? 'node-editor' : 'edge-editor';
cell.removeTool(name);
cell.addTools({
name,
args: {
event: e,
attrs: {
backgroundColor: isNode ? '#EFF4FF' : '#FFF'.fontSize: 18,}}}); });Copy the code