<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Tutorial Demo</title>
</head>
<style>
.g6-minimap-container {
border: none;
position: absolute !important;
right: 0px;
bottom: 0px;
background-color: #effcf6;
}
.g6-minimap-viewport {
border: 1px solid #999 !important;
}
</style>
<body>
<div style="height:800px;position: relative;">
<div id="container" style="height: 100%;"></div>
</div>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-3.7.1/dist/g6.min.js"></script>
<script>
const data = {
id: '0',
label: '深圳市',
anchorPoints: [
[1, 0.5],
],
children: [
{
id: '1',
label: '宝安区',
anchorPoints: [
[1, 0.5],
[0, 0.5]],
children: [
{ id: '2', label: '第三个', anchorPoints: [[0, 0.5]], type: 'addCustomNode' },
{ id: '3', label: '第四个', anchorPoints: [[0, 0.5]], type: 'addCustomNode' },
]
},
{
id: '4',
label: '龙岗区',
anchorPoints: [
[1, 0.5],
[0, 0.5]],
children: [
{
id: '5',
label: '第六个',
anchorPoints: [
[1, 0.5],
[0, 0.5]],
type: 'subCustomNode',
children: [
{ id: '6', label: '第七个', },
{ id: '19', label: '第四个', anchorPoints: [[0, 0.5]], },
{ id: '20', label: '第四个', anchorPoints: [[0, 0.5]], },
]
},
{
id: '7',
label: '第六个',
anchorPoints: [
[1, 0.5],
[0, 0.5]],
type: 'subCustomNode',
children: [
{ id: '8', label: '第七个', },
// { id: '15', label: '第四个', anchorPoints: [[0, 0.5]], },
// { id: '16', label: '第四个', anchorPoints: [[0, 0.5]], },
{ id: '17', label: '第四个', anchorPoints: [[0, 0.5]], },
{ id: '18', label: '第四个', anchorPoints: [[0, 0.5]], },
]
},
]
},
{
id: '9',
label: '宝安区',
anchorPoints: [
[1, 0.5],
[0, 0.5]],
children: [
{ id: '10', label: '第三个', anchorPoints: [[0, 0.5]], type: 'addCustomNode' },
{ id: '11', label: '第四个', anchorPoints: [[0, 0.5]], type: 'addCustomNode' },
]
},
{
id: '12',
label: '福田区',
anchorPoints: [[0, 0.5], [1, 0.5]],
children: [
{ id: '13', label: '第三个', anchorPoints: [[0, 0.5]], type: 'addCustomNode' },
{ id: '14', label: '第四个', anchorPoints: [[0, 0.5]], type: 'addCustomNode' },
]
},
]
}
// // 注册自定义节点
G6.registerNode(
'addCustomNode',
{
// draw:(cfg, group)=> {
// return group.addShape('dom', {
// attrs: {
// width: cfg.size[0],
// height: cfg.size[1],
// // DOM's html
// html: `
// <div style="height:95%;border:1px solid #999;text-align:center;line-height:${cfg.size[1]}px">${cfg.label}
// <span style="width:40px;height:100%;float:right;font-size:32px;color:#999;border-left:1px solid #999">
// +
// <span>
// </div>
// `
// },
// draggable: true,
// });
// },
// 绘制节点
drawShape: function drawShape(cfg, group) {
const shapeType = this.shapeType;
const style = Object.assign({}, this.getShapeStyle(cfg), {
stroke: '#c5c6c6',
width: 200,
height: 40
})
const shape = group.addShape(shapeType, {
attrs: style,
name: 'key-shape',
});
group.addShape('path', {
attrs: {
path:[['M',80,-16],['L',80,17]],
stroke: '#c5c6c6',
},
});
group.addShape('rect', {
attrs: {
x: 80,
y: -19,
width: 38,
height: 38,
fill: '#fff',
// stroke: '#8c8ba1',
cursor: 'pointer',
},
name: 'add-rect-shape',
});
group.addShape('path', {
attrs: {
path: [['M', 95, 0], ['L', 105, 0]],
stroke: '#8c8ba1',
cursor: 'pointer',
},
name: 'rect-shape',
});
group.addShape('path', {
attrs: {
path: [['M', 100, -5], ['L', 100, 5]],
stroke: '#8c8ba1',
},
});
return shape;
}
},'rect');
G6.registerNode(
'subCustomNode',
{
// 绘制节点
drawShape: function drawShape(cfg, group) {
const shapeType = this.shapeType;
const style = Object.assign({}, this.getShapeStyle(cfg),{
stroke: '#c5c6c6',
width:200,
height:40
})
const shape = group.addShape(shapeType, {
attrs: style,
name: 'key-shape',
});
group.addShape('rect', {
attrs: {
x:80,
y:-19,
width: 38,
height:38,
fill: '#fff',
cursor: 'pointer',
},
name: 'rect-shape',
});
group.addShape('path', {
attrs: {
path: [['M', 80, -16], ['L', 80, 17]],
stroke: '#c5c6c6',
cursor: 'pointer',
},
name: 'rect-shape',
});
group.addShape('path', {
attrs: {
path: [['M', 95, 0], ['L', 105, 0]],
stroke: '#8c8ba1',
cursor: 'pointer',
},
name: 'subCustomNode-shape',
});
return shape;
}
}, 'rect');
G6.registerEdge(
'line',
{
getPath(points) {
const startPoint = points[0];
const endPoint = points[1];
return [
['M', startPoint.x + 10, startPoint.y],
['L', endPoint.x - 10, endPoint.y],
];
},
afterDraw(cfg, group) {
// 获取图形组中的第一个图形,在这里就是边的路径图形
const shape = group.get('children')[0];
// 获取路径上的起点坐标
const quatile = shape.getPoint(0);
// 在起点终点上放置一个圆形
group.addShape('circle', {
attrs: {
r: 3,
stroke: '#c5c6c6',
x: quatile.x - 2,
y: quatile.y,
},
});
const quatileEnd = shape.getPoint(1);
group.addShape('circle', {
attrs: {
r: 3,
stroke: '#c5c6c6',
x: quatileEnd.x + 3,
y: quatileEnd.y,
},
});
},
update: undefined,
},
'line'
);
const minimap = new G6.Minimap({
size: [150, 100],
});
const initTree = (data) => {
// 画布宽高
const width = document.getElementById('container').scrollWidth || 800;
const height = document.getElementById('container').scrollHeight || 800;
const graph = new G6.TreeGraph({
// 图的 DOM 容器,可以传入该 DOM 的 id 或者直接传入容器的 HTML 节点对象。
container: 'container',
// 指定画布宽度,单位为 'px'。
width,
// 指定画布高度,单位为 'px'。
height,
// 是否开启画布自适应。开启后图自动适配画布大小。
fitView: true,
fitViewPadding: [10, 10, 10, 10],
// v3.5.1 后支持。开启后,图将会被平移,图的中心将对齐到画布中心,但不缩放。优先级低于 fitView
fitCenter: true,
// 最小缩放比例
minZoom: 0.8,
// 最大缩放比例
maxZoom: 2,
// 指定边是否连入节点的中心
// linkCenter: true,
// 设置画布的模式
modes: {
default: [
{
// 只适用于树图,展开或收起子树
type: 'collapse-expand',
// trigger:收起和展开节点分组的方式。支持 'click' 和 'dblclick' 两种方式。默认为 'dblclick',即双击。
trigger: 'click',
// onChange:收起或展开的回调函数。警告:V3.1.2 版本中将移除;
onChange: async function onChange(item, collapsed) {
// const data = item.get('model').data;
const { _cfg } = item
console.log(item);
const dataItem = item.getModel();
dataItem.collapsed = collapsed;
item.updatePosition(_cfg)
return true;
},
},
// 拖拽画布;
'drag-canvas',
// 缩放画布;
'zoom-canvas',
],
},
// renderer: "svg",
// 默认状态下节点的配置,比如 type, size, color。会被写入的 data 覆盖。
defaultNode: {
type: 'rect',
// size 是单个数字,表示直径
// size: 16,
// 指定边连入节点的连接点的位置(相对于该节点而言),可以为空。例如: [0, 0],代表节点左上角的锚点,[1, 1],代表节点右下角的锚点
// anchorPoints: [
// [1,0.5],
// [0,0.5],
// [0, 0.5]
// ],
// 节点样式
style: {
// 节点填充色
fill: '#fff',
// 节点的描边颜色,''就是没颜色的意思
stroke: '#c5c6c6',
// 那个小手
cursor: 'pointer',
radius: 2,
},
// Object 类型。配置标签文本
labelCfg: {
// 标签的样式属性。
style: {
// 文本颜色
fill: '#000',
// 文本字体大小
fontSize: 14,
},
},
},
// 默认状态下边的配置,比如 type, size, color。会被写入的 data 覆盖。
defaultEdge: {
// 指定边的类型,可以是内置边的类型名称,也可以是自定义边的名称。默认为 'line'
type: 'line',
// 边的样式属性
style: {
// 边的颜色
stroke: '#ccc',
},
},
// 布局配置项,使用 type 字段指定使用的布局方式
layout: {
// 布局名称
type: 'compactBox',
// layout 的方向。
direction: 'LR', // H / V / LR / RL / TB / BT
// 节点 id 的回调函数
getId: function getId(d) {
return d.id;
},
// 节点高度的回调函数
getHeight: function getHeight() {
return 16;
},
// 节点宽度的回调函数
getWidth: function getWidth() {
return 16;
},
// 节点纵向间距的回调函数
getVGap: function getVGap() {
return 20;
},
// 节点横向间距的回调函数
getHGap: function getHGap() {
return 120;
},
},
plugins: [minimap],
// 动画
animate: true,
});
// 设置各个节点样式及其他配置,以及在各个状态下节点的 KeyShape 的样式
// 该方法必须在 render 之前调用,否则不起作用
// 使用 graph.node(nodeFn) 配置 > 数据中动态配置 > 实例化图时全局配置
graph.node(function (node) {
return {
label: node.label,
size: [160, 40],
labelCfg: {
style: {
textAlign: 'center',
},
},
};
});
graph.on('add-rect-shape:click', (evt) => {
const { item } = evt;
console.log(item);
// graph.updateItem(item, {
// label: '点击了局部',
// labelCfg: {
// style: {
// fill: '#003a8c',
// fontSize: 16,
// },
// },
// });
});
// 初始化的图数据
graph.data(data);
// 根据提供的数据渲染视图。
graph.render();
// 让画布内容适应视口
graph.fitView();
}
initTree(data)
</script>
</body>
</html>
antV G6 自定义节点 实现流程图 + 小地图功能
最新推荐文章于 2024-05-24 10:00:02 发布