设置可缩放 拖动画布
let graph = new G6.Graph({
modes: {
// 拖拽画布 缩放画布
default: ['drag-canvas', 'zoom-canvas']
}
})
内容缩放居中
graph.zoom(0.5) // 缩放到0.5
graph.fitCenter() //将图中心将对齐到画布中心
连接点的设置
连接点 // 全局默认配置
let graph = new G6.Graph({
defaultNode: {
anchorPoints: [[0.5, 0],[1, 0.5],[0.5, 1],[0, 0.5],[0.85, 0.15],[0.85, 0.85],[0.15, 0.85],[0.15, 0.15]],
},
})
// 自定义节点配置
G6.registerNode('labelBox', {
draw(){...},
getAnchorPoints() {
return [[0.5, 0],[1, 0.5],[0.5, 1],[0, 0.5],[1, 0],[1, 1],[0, 1],[0, 0]];
}
})
// 使用 边data中
{
id: 'g8',
source: 'g8',
target: 'g8Label',
sourceAnchor: 7, // anchorPoints数组中下标为7的[0, 0] 左上
targetAnchor: 5, // anchorPoints数组中下标为5的[1, 1] 右下
type: 'labelBox'
},
图片旋转
旋转会导致anchorPoints跟着转。 思路: 1.添加一个框 2.框里添加图片 3.旋转图片,框不变
旋转 // 引入转换方法
import { ext } from '@antv/matrix-util';
const transform = ext.transform;
G6.registerNode(type, {
draw(cfg, group) { // 添加框
const keyShape = group.addShape('rect', {...})
return keyShape
},
afterDraw(cfg, group) { //添加img
let direction = cfg.direction
let image = group.addShape('image', {})
if(direction && direction === 'v') {
const newMatrix = transform([1, 0, 0, 0, 1, 0, 0, 0, 1], [
['t', 0,-34], // 位移 包含框不同 自行设置
['r', Math.PI / 2], // 旋转90度
]);
image.setMatrix(newMatrix); // 图片变化
}
}
})
自定义添加文字
自定义节点或边添加文本时 需要addShape('text')
// 节点文本
G6.registerNode(type, {
draw(cfg, group) {
const keyShape = group.addShape('rect', {...})
if (cfg.label) {
const label = group.addShape('text', {
attrs: {
x: positionX, // 相对于节点的偏移
y: positionY, //
},
name: 'text-za',
});
}
return keyShape
}
})
边文的 xy坐标 是相对于整个容器的,不是所在线的xy坐标
// 边文本
G6.registerEdge(type, {
draw(cfg, group) {
const keyShape = group.addShape('path', {...})
if (cfg.label) {
let {startPoint,endPoint} = cfg
const label = group.addShape('text', {
attrs: {
x: startPoint.x - endPoint.x, // 居中 线段起点终点的
y: startPoint.y - endPoint.y, // 坐标系跟节点的坐标一样
},
name: 'text-za',
});
}
return keyShape
}
})
自定义边文本的旋转
旋转
if (cfg.label) {
let direction = cfg.textDirection && cfg.textDirection === 'v'
let label = group.addShape('text', {
attrs: {
x: direction ? 0 : x, //需要旋转是 先设置位置为0
y: direction ? 0 : y,
text: cfg.label,
fontSize:8,
fill: '#aaa',
lineHeight: 18, // 行高 renderer方式是svg是无效 默认canvas
zIndex:1000
},
name: 'left-text-shape',
});
// 文本垂直
if(direction) {
//transform 看图片旋转
const newMatrix = transform([1, 0, 0, 0, 1, 0, 0, 0, 1], [
['t', yPosition,12 - xPosition], // // 这个时候才移动文字的位置
['r', Math.PI / 2],
]);
label.setMatrix(newMatrix);
}
}
定义边 虚线
// 添加虚线
afterDraw(cfg, group) {
// 获得该边的第一个图形,这里是边的 path
const shape = group.get('children')[0];
shape.attr('lineDash', [7, 3, 2, 3]); // 虚线、实线 的长度
}
交互 设置状态 改变图片
G6.registerNode(type, {
options: {
stateStyles: {
'status:default': {
img: vedio0Img
},
'status:pass': {
img: vedio1Img
},
'status:stop': {
img: vedio2Img
}
}
},
draw(cfg, group) {
const keyShape = group.addShape('image', {
attrs: {
x: typeObj.x,
y: typeObj.y,
img: (this.options.stateStyles[cfg.img] || {}).img || this.options.stateStyles['status:default'].img,
width: cfg.width || typeObj.width,
height: cfg.height || typeObj.height,
cursor: 'pointer', // 鼠标样式
},
name: 'img_node',
});
},
setState(name, value, item) {
const shape = item.get('keyShape')
let stateStyles = item._cfg.styles || {}
if (!!value) {
if(name === 'status') {
let newKey = `${name}:${value}`
if(stateStyles[newKey]) {
shape.attr('img', stateStyles[newKey].img);
}
}
} else {
// 恢复默认图片
if(Object.keys(stateStyles).includes(name)) {
shape.attr('img', stateStyles['status:default'].img);
}
}
}
})
//执行
let g = this.graph.findById('g1')
this.graph.setItemState(g, 'status', 'pass') // 设置状态
this.graph.clearItemStates(g, ['status:pass']); // 清除状态 方式1
this.graph.clearItemStates(g); // 清除状态 方式2
}
虚线动画
// 添加虚线
afterDraw(cfg, group) {
const shape = group.get('children')[0];
shape.attr('lineDash', [7, 3, 2, 3]); // 虚线、实线 的长度
},
setState(name, value, item) {
const shape = item.get('keyShape')
let currStatusArr = item.getStates() // 当前选中的状态
if (!!value) {
// 添加动画
if(currStatusArr.includes('animation') && value) {
let index = 0;
shape.animate(() => {
index++;
if (index > 60) {
index = 0;
}
// 虚线的所有边长 * 4 = 60
let a = -(index / 4)
const res = {
lineDash:[7, 3, 2, 3], // 加起来有15
lineDashOffset: a,
};
return res;
},
{
repeat: true, // 动画重复
duration: 3000, // 一次动画的时长为 3000
});
}
} else {
// 取消动画
if(name === 'animation'){
shape.stopAnimate();
item.toBack() // 元素实例方法 将元素设置到最底层
}
}
}
修改自定义文本
let arr = this.graph.getNodes()
for(let i=0;i<arr.length;i++) {
let obj = arr[i].getModel()
arr[i].update({ label: 13 })
}
// 自定义节点
draw(cfg, group) {
const label = group.addShape('text', {})
},
update (cfg, node) { // 修改时触发update
const group = node.getContainer(); // 获取容器
const shape = group.get('children')[1]; // 按照添加的顺序
shape.attr('text',cfg.label)
}
点击事件
graph.data(data);
graph.render(); // 渲染图
graph.on('click', (ev) => {
let type = ev.item._cfg.currentShape // 自定义节点的type
switch(type){
case 'vedioImg':
this.clickVedio(ev)
break;
default:
console.log(type)
}
});
菜单 弹窗
菜单 const menu = this.getMenu()
let graph = new G6.Graph({
plugins: [menu], // 配置插件 menu属于插件
})
//菜单 样式需要页面的css中
getMenu () {
let _this = this
return new G6.Menu({
offsetX: 0,
offsetY: 0,
className: 'vedioListItemBox',
trigger: 'click', // 触发类型
getContent (e) {
// 添加dom
const outDiv = document.createElement('div')
outDiv.classList.add("vedioListItem");
let arr = e.item.getModel().vList
let strDiv = arr.map((ele) => {
let data = JSON.stringify(ele)
return `<div data-info='${data}'> ${ele.channelName} </div>`
})
outDiv.innerHTML = `${strDiv.join(' ')}`
return outDiv
},
// 设置是否显示
shouldBegin(G6Event){
// 返回boolean 值 true显示
let obj = G6Event.item.get('model') || {}
return obj.type === 'vedioImg' && obj.label
},
// 设置是否显示 处理点击
handleMenuClick(target) {
if(target.nodeType === 1) {
let data = target.getAttribute("data-info")
data = JSON.parse(data)
console.log(data )
}
}
})
}
标签:g6,4.7,group,img,cfg,antv,let,graph,const
From: https://www.cnblogs.com/voxov/p/17014172.html