MyComponent
import React from 'react';
import styles from './index.less';
export default class MyComponenAdd extends React.Component {
shouldComponentUpdate() {
const node = this.props.node;
if (node) {
if (node.hasChanged('data')) {
return true;
}
}
return false;
}
handleClick = () => {
this.props.getType(this.props.node.store.data.type);
};
render() {
const { node } = this.props;
return (
<div
className={styles.box}
dangerouslySetInnerHTML={{ __html: node.store.data.label }}
onClick={this.handleClick}
/>
);
}
}
publicStyle
let publicStyle = {
shape: 'my-rect',
lineShape: 'edge',
positionList: [
{
x: 0,
y: 140,
},
{
x: 250,
y: 140,
},
{
x: 500,
y: 140,
},
{
x: 750,
y: 140,
},
{
x: 250,
y: 280,
},
],
attrs: {
body: {
rx: 6,
ry: 6,
},
},
lineAttrs: {
line: {
stroke: '#a30014',
targetMarker: {
width: 12,
height: 8,
},
},
},
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',
id: '125c00ca-08dd-44f1-b22f-06c06e43ecb5',
},
{
group: 'right',
id: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
},
{
group: 'bottom',
id: '69b15387-d6f4-43e7-8282-40fe5ad78505',
},
{
group: 'left',
id: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
},
],
},
labelList: [
`<div style="line-height:70px">工单A</div>`,
`<div style="line-height:33px">工单B<br/><a href="#">B</a></div>`,
`<div style="line-height:33px">工单C<a href="#">C</a></div> `,
`<div style="line-height:33px"><a href="#">工单D</a><br/><div>`,
`<div style="line-height:33px">工单E<br/><a href="#">运营E</a></div>`,
],
};
export default publicStyle;
index
import React, { useEffect } from 'react';
import { Graph, Shape } from '@antv/x6';
import '@antv/x6-react-shape';
import insertCss from 'insert-css';
import publicStyle from './publicStyle';
import MyComponent from './MyComponent';
let graph = null;
export default function AntvDemo() {
useEffect(() => {
preWork();
graph = new Graph({
container: document.getElementById('container_antdx6'),
grid: false,
panning: false,
interacting: {
nodeMovable: false,
},
mousewheel: {
enabled: false,
},
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: '#808080',
strokeWidth: 2,
targetMarker: {
name: 'block',
width: 12,
height: 8,
},
},
},
zIndex: 0,
});
},
validateConnection({ targetMagnet }) {
return !!targetMagnet;
},
},
});
Graph.registerNode(
'my-rect',
{
inherit: 'react-shape',
x: 200,
y: 150,
width: 180,
height: 70,
attrs: {
body: {
stroke: '#000',
fill: '#fff',
rx: 10,
ry: 10,
},
label: {
fill: '#000',
fontSize: 12,
},
},
component: <MyComponent getType={getType} />,
},
true,
);
graph.fromJSON([
{
shape: publicStyle.lineShape,
attrs: { ...publicStyle.lineAttrs },
id: '8734eb26-5641-435b-b5b2-d926709406fc',
zIndex: 0,
source: {
cell: 'a14fb6b4-5213-466d-aee9-4b2bc17e3e6a',
port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
},
target: {
cell: 'efe4bd07-7d6e-4ab0-88f4-7df69a0769a3',
port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
},
},
{
shape: publicStyle.lineShape,
attrs: { ...publicStyle.lineAttrs },
id: '151d4994-c04a-4dea-8c94-f5b08f035b1e',
zIndex: 0,
source: {
cell: 'a14fb6b4-5213-466d-aee9-4b2bc17e3e6a',
port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
},
target: {
cell: '94c5b26d-585f-49cf-a531-c51786a61eda',
port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
},
},
{
shape: publicStyle.lineShape,
attrs: { ...publicStyle.lineAttrs },
id: '9c850d5c-369d-4e02-90ad-1210f6b67a59',
zIndex: 0,
source: {
cell: 'efe4bd07-7d6e-4ab0-88f4-7df69a0769a3',
port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
},
target: {
cell: '32cbc0e8-36a2-41c7-b24d-5b59c0928d81',
port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
},
},
{
shape: publicStyle.lineShape,
attrs: { ...publicStyle.lineAttrs },
id: 'e6d8b145-c7e2-49df-952f-563a9ea43df4',
zIndex: 0,
source: {
cell: '94c5b26d-585f-49cf-a531-c51786a61eda',
port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
},
target: {
cell: '32cbc0e8-36a2-41c7-b24d-5b59c0928d81',
port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
},
},
{
shape: publicStyle.lineShape,
attrs: { ...publicStyle.lineAttrs },
id: '9e392cd2-7113-49c2-95c9-925321bc80ad',
zIndex: 0,
source: {
cell: '32cbc0e8-36a2-41c7-b24d-5b59c0928d81',
port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
},
target: {
cell: '9763d660-d0ff-4663-b00d-d5c4d057d0f9',
port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
},
},
{
shape: publicStyle.shape,
label: publicStyle.labelList[0],
position: { ...publicStyle.positionList[0] },
attrs: { ...publicStyle.attrs },
ports: { ...publicStyle.ports },
type: '0',
id: 'a14fb6b4-5213-466d-aee9-4b2bc17e3e6a',
zIndex: 1,
},
{
shape: publicStyle.shape,
label: publicStyle.labelList[1],
position: { ...publicStyle.positionList[1] },
attrs: { ...publicStyle.attrs },
ports: { ...publicStyle.ports },
type: '1',
id: 'efe4bd07-7d6e-4ab0-88f4-7df69a0769a3',
zIndex: 2,
},
{
shape: publicStyle.shape,
label: publicStyle.labelList[2],
position: { ...publicStyle.positionList[2] },
attrs: { ...publicStyle.attrs },
ports: { ...publicStyle.ports },
type: '2',
id: '32cbc0e8-36a2-41c7-b24d-5b59c0928d81',
zIndex: 3,
},
{
shape: publicStyle.shape,
label: publicStyle.labelList[3],
position: { ...publicStyle.positionList[3] },
attrs: { ...publicStyle.attrs },
ports: { ...publicStyle.ports },
type: '3',
id: '9763d660-d0ff-4663-b00d-d5c4d057d0f9',
zIndex: 4,
},
{
shape: publicStyle.shape,
label: publicStyle.labelList[4],
position: { ...publicStyle.positionList[4] },
attrs: { ...publicStyle.attrs },
ports: { ...publicStyle.ports },
type: '4',
id: '94c5b26d-585f-49cf-a531-c51786a61eda',
zIndex: 5,
},
]);
}, []);
const getType = (type) => {
console.log('🚀 ~ file: index.jsx:771 ~ getType ~ type', type);
};
const preWork = () => {
const container = document.getElementById('content_wrap');
const graphContainer = document.createElement('div');
graphContainer.id = 'container_antdx6';
container.appendChild(graphContainer);
insertCss(`
#container {
height:100%;
display: flex;
border: 1px solid #dfe3e8;
}
#container_antdx6 {
width: 100%;
height: 100%;
}
.x6-widget-transform {
margin: -1px 0 0 -1px;
padding: 0px;
border: 1px solid #239edd;
}
.x6-widget-transform > div {
border: 1px solid #239edd;
}
.x6-widget-transform > div:hover {
background-color: #3dafe4;
}
.x6-widget-transform-active-handle {
background-color: #3dafe4;
}
.x6-widget-transform-resize {
border-radius: 0;
}
.x6-widget-selection-inner {
border: 1px solid #239edd;
}
.x6-widget-selection-box {
opacity: 0;
}
`);
};
return (
<div style={{ height: '400px' }}>
<div id="content_wrap" style={{ height: '400px' }}></div>
</div>
);
}
版本
- @antv/x6:^1.34.5
- @antv/x6-react-shape:^1.6.3
注意事项
- 如果报错 insertCss
npm i insert-css -S