g6/demos/internal-node-rect.html

331 lines
7.7 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>默认的图片节点</title>
</head>
<body>
<div id="mountNode"></div>
<div id="mountNode1"></div>
<script src="../build/g6.js"></script>
<script>
const edgeTypeColorMap = {
type1: ['#531dab', '#391085', '#391085'],
type2: ['#d9d9d9', '#bfbfbf', '#8c8c8c'],
type3: ['#d3adf7', '#b37feb', '#9254de']
}
const generateArrow = (lineWidth) => {
let width = (lineWidth * 4) / 3;
return [
['M', lineWidth / 2, 0],
['L', -width * 1.5, -width * 1.5],
['L', -width * 1.5, width * 1.5],
// ['A', radius, radius, 0, 0, 1, -width / 2, halfHeight],
['Z']
];
}
const defaultConf = {
style: {
lineAppendWidth: 5,
lineDash: [0, 0],
lineDashOffset: 0,
endArrow: true,
opacity: 1,
labelCfg: {
style: {
fillOpacity: 1
}
}
},
/**
* 绘制边
* @override
* @param {Object} cfg 边的配置项
* @param {G.Group} group 边的容器
* @return {G.Shape} 图形
*/
drawShape(cfg, group) {
const item = group.get('item')
const shapeStyle = this.getShapeStyle(cfg, item);
const shape = group.addShape('path', {
className: 'edge-path',
attrs: shapeStyle
});
return shape;
},
drawLabel(cfg, group) {
const labelCfg = cfg.labelCfg || {}
const labelStyle = this.getLabelStyle(cfg, labelCfg, group)
const text = group.addShape('text', {
attrs: {
...labelStyle,
text: cfg.label,
fontSize: 12,
fill: '#404040',
cursor: 'pointer'
},
className: 'edge-label'
})
return text
},
/**
* 获取图形的配置项
* @internal 仅在定义这一类节点使用,用户创建和更新节点
* @param {Object} cfg 节点的配置项
* @return {Object} 图形的配置项
*/
getShapeStyle(cfg, item) {
const { startPoint, endPoint } = cfg
const type = item.get('type')
const defaultStyle = this.getStateStyle('default', true, item)
if(type === 'node') {
return Object.assign({}, cfg.style, defaultStyle);
}
const controlPoints = this.getControlPoints(cfg);
let points = [ startPoint ]; // 添加起始点
// 添加控制点
if (controlPoints) {
points = points.concat(controlPoints);
}
// 添加结束点
points.push(endPoint);
const path = this.getPath(points);
const style = Object.assign({}, { path }, cfg.style, defaultStyle);
return style;
},
getControlPoints(cfg) {
let controlPoints = cfg.controlPoints; // 指定controlPoints
if (!controlPoints || !controlPoints.length) {
const { startPoint, endPoint } = cfg;
const innerPoint = G6.Util.getControlPoint(startPoint, endPoint, 0.5, cfg.edgeOffset || 30);
controlPoints = [ innerPoint ];
}
return controlPoints;
},
/**
* 获取三次贝塞尔曲线的path
*
* @param {array} points 起始点和两个控制点
* @returns
*/
getPath(points) {
const path = [];
path.push([ 'M', points[0].x, points[0].y ]);
path.push([ 'Q', points[1].x, points[1].y, points[2].x, points[2].y ]);
return path;
},
/**
* 根据不同状态,获取不同状态下的样式值
* @param {string} name
* @param {string} value
* @param {Item} item
*/
getStateStyle(name, value, item) {
const model = item.getModel()
const { style = {} } = model
const defaultStyle = Object.assign({}, this.style)
// 更新颜色
return {
...defaultStyle,
lineWidth: 1,
stroke: edgeTypeColorMap[model.edgeType] && edgeTypeColorMap[model.edgeType][0],
...style
}
},
/**
* 拖动时更新path及边的label
*
* @param {object} cfg 边的model
* @param {Edge} item 边的实例
*/
update(cfg, item) {
const { data, style,
startPoint, endPoint, labelCfg = {} } = cfg
const group = item.getContainer()
const model = data || cfg
let arrowWidth = 2
const defaultStyle = Object.assign({}, this.style, {
lineWidth: 1,
stroke: edgeTypeColorMap[model.edgeType] && edgeTypeColorMap[model.edgeType][0],
endArrow: {
path: generateArrow(arrowWidth),
}
}, style)
const { opacity, onlyHideText } = defaultStyle
// 更新 path
const keyShape = item.getKeyShape();
const controlPoints = this.getControlPoints(cfg);
keyShape.attr({
path: [
['M', startPoint.x, startPoint.y],
['Q', controlPoints[0].x, controlPoints[0].y, endPoint.x, endPoint.y]
],
...defaultStyle
});
const labelStyle = this.getLabelStyle(cfg, labelCfg, group);
const text = group.findByClassName('edge-label');
const attrs = _.omit({
...labelStyle,
fillOpacity: onlyHideText ? 0 : opacity === 0 ? opacity : 1,
fill: '#404040'
}, 'stroke')
if(text) {
text.resetMatrix();
text.attr(attrs);
}
}
};
G6.registerEdge('quadratic-label-edge', defaultConf, 'quadratic');
// let nodes = []
// for(let i = 0; i < 500; i++) {
// nodes.push({
// id: `node-${i}`,
// label: `label-${i}`,
// x: Math.random() * 650,
// y: Math.random() * 550
// })
// }
const data = {
nodes: [
{
id: 'node1',
label: 'node1'
},
{
id: 'node2',
label: 'node2'
}
],
edges: [
{
source: 'node1',
target: 'node2',
edgeType: 'type1'
},
{
source: 'node2',
target: 'node1',
edgeType: 'type2'
},
{
source: 'node1',
target: 'node2',
edgeType: 'type3',
edgeOffset: -10
}
]
}
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultNode: {
shape: 'rect',
size: [60, 30],
color: 'green',
style: {
// fill: 'red',
// stroke: '#eaff8f',
lineWidth: 5
},
labelCfg: {
style: {
fill: '#9254de',
fontSize: 18
}
},
linkPoints: {
top: true,
bottom: true,
left: true,
right: true,
size: 5,
fill: '#fff'
}
},
defaultEdge: {
shape: 'quadratic-label-edge'
},
nodeStateStyles: {
hover: {
fill: '#d3adf7'
}
},
modes: {
default: ['drag-canvas', 'drag-node', {
type: 'brush-select',
trigger: 'ctrl'
}]
}
})
graph.data(data)
graph.render()
graph.on('node:click', evt => {
const { item } = evt
graph.setItemState(item, 'select', true)
graph.updateItem(item, {
size: [ 260, 130],
style: {
opacity: 0.6
},
preRect: {
fill: 'blue'
},
linkPoints: {
fill: '#fff',
size: 5
},
stateIcon: {
img: 'https://gw.alipayobjects.com/zos/basement_prod/c781088a-c635-452a-940c-0173663456d4.svg'
}
})
})
graph.on('node:mouseenter', evt => {
const { item } = evt
graph.setItemState(item, 'hover', true)
})
graph.on('node:mouseleave', evt => {
const { item } = evt
graph.setItemState(item, 'hover', false)
})
// graph.addItem('group', {
// nodes: ['image', 'triangle'],
// type: 'rect',
// zIndex: 0,
// title: {
// text: '名称'
// }
// })
</script>
</body>
</html>