g6/demos/internal-node-rect.html
2020-02-14 11:30:12 +08:00

347 lines
9.2 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>