性能形容 x6(注:id 为 123)
1、g6 装置
2、自定义元素(平行四边形)
3、新增、编辑、删除
4、关系新增、编辑、删除
5、悬浮展现气泡
6、元素拖拽获取地位
7、元素显示与暗藏
8、悬停关联线高亮线两边元素
9、选中元素,高亮以后元素及关系兄弟节点及线
10、点击空白处,革除标记状态
g6 装置
npm install --save @antv/g6
初始化画布
plugins:存储的为插件容器
container:String | HTMLElement,必须,在 Step 1 中创立的容器 id 或容器自身
width:图的宽度
height:图的高度
fitView:视图居中
defaultNode:默认元素款式
defaultEdge:默认线款式(设置透明度为 0.2,避免线太多,看着错乱)
this.graph = new G6.Graph({plugins: ['tooltip'], // 配置 插件
container: "g-container", // String | HTMLElement,必须,在 Step 1 中创立的容器 id 或容器自身
width: 800, // Number,必须,图的宽度
height: 500, // Number,必须,图的高度
fitView: true,
defaultNode: {size: [34, 34],
style: {
fill: "#ffffff",
stroke: "rgba(0,0,0,.35)",
lineWidth: 2,
cursor: "pointer",
radius: [2, 2],
opacity: 0.2,
},
labelCfg: {
style: {fontSize: 14,},
position: "bottom",
offset: 5,
},
},
defaultEdge: {
type: "line",
color: "#999999",
style: {
opacity:0.2,
cursor: "pointer",
endArrow: {path: G6.Arrow.vee(6, 5, 0),
d: 0,
fill: "red",
cursor: "pointer",
lineDash: [0],
},
},
labelCfg: {
autoRotate: true,
style: {
background: {
fill: "#ffffff",
stroke: "#000000",
padding: [2, 2, 2, 2],
radius: 2,
cursor: "pointer",
},
},
},
},
},
modes: {
default: [
{
type: "zoom-canvas",
enableOptimize: true,
optimizeZoom: 0.9,
},
{
type: "drag-canvas",
enableOptimize: true,
},
"drag-node",
"brush-select",
"click-select",
],
},
});
读取 Step 2 中的数据源到图上
this.graph.data(this.data); // 读取 Step 2 中的数据源到图上
渲染图
this.graph.render(); // 渲染图
气泡悬浮提醒(插件)
// 提醒
const tooltip = new G6.Tooltip({
offsetX: 10,
offsetY: 40,
getContent: (e) => {const outDiv = document.createElement("div");
outDiv.style.width = "fit-content";
outDiv.style.height = "fit-content";
const model = e.item.getModel();
if (e.item.getType() === "node") {// 判断是元素还是关系线
outDiv.innerHTML = `${model.id}`;
} else {const source = e.item.getSource();
const target = e.item.getTarget();
outDiv.innerHTML = ` 起源:${source.getModel().id}<br/> 去向:${target.getModel().id
}`;
}
return outDiv;
},
});
自定义元素
// 自定义一个名为 quadrilateral 的节点,通过数据 type 来判断元素
G6.registerNode(
"quadrilateral",
{draw(cfg, group) {const size = this.getSize(cfg); // 转换成 [width, height] 的模式
const color = cfg.color;
const width = size[0];
const height = size[1];
// / 1 \
// 4 2
// \ 3 /
const path = [["M", -width / 4, 0 - height / 1.5], // 上部顶点
["L", width / 2, 0 - height / 1.5], // 右侧顶点
["L", width / 4, 0], // 下部顶点
["L", -width / 2, 0], // 左侧顶点
["Z"], // 关闭
];
const style = {path: path, stroke: color, ...cfg.style};
// 减少一个 path 图形作为 keyShape
const keyShape = group.addShape("path", {
attrs: {...style,},
draggable: true,
name: "diamond-keyShape", // 在 G6 3.3 及之后的版本中,必须指定 name,能够是任意字符串,但须要在同一个自定义元素类型中放弃唯一性
});
// 返回 keyShape
return keyShape;
},
afterDraw(cfg, group) {const size = this.getSize(cfg); // 转换成 [width, height] 的模式
const color = cfg.color;
const width = size[0];
const height = size[1];
// / 1 \
// 4 2
// \ 3 /
const path = [["M", -width / 4, 0 - height / 1.5], // 上部顶点
["L", width / 2, 0 - height / 1.5], // 右侧顶点
["L", width / 4, 0], // 下部顶点
["L", -width / 2, 0], // 左侧顶点
["Z"], // 关闭
];
const style = {path: path, stroke: color, ...cfg.style};
// 减少一个 path 图形作为 keyShape
const keyShape = group.addShape("path", {
attrs: {...style,},
draggable: true,
name: "diamond-keyShape", // 在 G6 3.3 及之后的版本中,必须指定 name,能够是任意字符串,但须要在同一个自定义元素类型中放弃唯一性
});
// 返回 keyShape
return keyShape;
},
},
// 留神这里继承了 'single-node'
"rect"
);
新增
从内部拖拽到画布上,先获取画布的地位坐标
point = this.graph.getPointByClient(e.clientX, e.clientY)
新增元素(rect 为正方形)
this.graph.addItem("node", {
x: point.x,// x 坐标
y: point.y,// y 坐标
label: "name",
type: "rect",
id:'123',
size: [100, 100],// 大小
style: {// 款式
lineWidth: 2,
stroke: "#00BBEF",
fill: "#DAF3FF",
},
nodeStateStyles: {// 状态款式
selected: {// 选中款式
lineWidth: 1,
stroke: "#00BBEF",
},
hover: {// 悬浮款式
lineWidth: 1,
stroke: "#00BBEF",
},
},
});
设置选中状态
this.graph.setItemState(item, "selected", true);
勾销选中状态
this.graph.setItemState(item, "selected", false);
设置悬浮状态
this.graph.setItemState(item, "hover", true);
勾销悬浮状态
this.graph.setItemState(item, "hover", false);
编辑更新元素
this.graph.updateItem("123", //id
{
x: point.x,// x 坐标
y: point.y,// y 坐标
label: "name",
type: "rect",
id:'123',
size: [100, 100],// 大小
style: {// 款式
lineWidth: 2,
stroke: "#00BBEF",
fill: "#DAF3FF",
},
nodeStateStyles: {// 状态款式
selected: {// 选中款式
lineWidth: 1,
stroke: "#00BBEF",
},
hover: {// 悬浮款式
lineWidth: 1,
stroke: "#00BBEF",
},
},
});
删除
this.graph.removeItem('123')
关系线新增
this.graph.addItem("edge", {
label: "name",
type: "line",
id:'edge123',
target:'node1',// 源
source:'node2',// 指标
style: {// 款式
lineWidth: 2,
lineDash:[8]// 虚线
},
nodeStateStyles: {// 状态款式
selected: {// 选中款式
lineWidth: 1,
stroke: "#00BBEF",
},
hover: {// 悬浮款式
lineWidth: 1,
stroke: "#00BBEF",
},
},
});
编辑更新关系
this.graph.updateItem("edge123", //id
{
label: "name",
type: "line",
id:'edge123',
target:'node1',// 源
source:'node2',// 指标
style: {// 款式
lineWidth: 2,
lineDash:[8]// 虚线
},
nodeStateStyles: {// 状态款式
selected: {// 选中款式
lineWidth: 1,
stroke: "#00BBEF",
},
hover: {// 悬浮款式
lineWidth: 1,
stroke: "#00BBEF",
},
},
});
删除关系
this.graph.removeItem('edge123')
拖拽元素
// 拖动 node 节点
this.graph.on("node:dragend", (ev) => {console.log(ev);
let{x,y} = ev.item.getModel()})
元素显示与暗藏
//node 为元素节点,123 为元素的 id
let node = this.graph.findById('123')
// 暗藏
node.hide()
// 显示
node.show()
悬停关联线高亮线两边元素
先监听关联线鼠标移入事件,再监听移除事件
鼠标移入时,高亮线及两边元素
鼠标移出时,勾销线及两边元素高亮
// 鼠标悬停线,高亮相干元素
this.graph.on("edge:mouseenter", (e) => {e.stopPropagation();
const source = e.item.getSource();
const target = e.item.getTarget();
// 高亮
this.graph.setItemState(source, "hover", true);
this.graph.setItemState(target, "hover", true);
this.graph.setItemState(e.item, "hover", true);
// 设置层级最前显示(避免被笼罩)source.toFront()
target.toFront()
e.item.toFront()
// 因为初始化了线通明的为 0.2,所有这里把透明度设置 1,不便查看
this.graph.updateItem(e.item,{style:{opacity:1}
})
});
// 鼠标悬停线,勾销高亮相干元素
this.graph.on("edge:mouseleave", (e) => {e.stopPropagation();
const source = e.item.getSource();
const target = e.item.getTarget();
// 勾销高亮
this.graph.setItemState(source, "hover", false);
this.graph.setItemState(target, "hover", false);
this.graph.setItemState(e.item, "hover", false);
this.graph.updateItem(e.item,{style:{opacity:0.2}
})
});
选中元素,高亮以后元素及关系兄弟节点及线
1、设置所有元素透明度 0.2
2、高亮过后点击元素,透明度为 1
3、判断线的源数据和指标数据是否和以后点击的节点有关系,有则高亮,无则显示暗度
this.graph.on("node:click",ev=>{if(!ev) return
let {id} = ev.tem.getModel()
this.graph.setItemState(id,'selected',true)
ev.item.toFront();
// 用于存储 id,革除之前的状态
this.positionId = id
// 设置所有元素透明度 0.2
this.graph.getNodes().forEach(node=>{this.graph.updateItem(node,{style:{opacity:0.2}})
})
// 高亮以后点击元素
this.graph.updateItem(ev.item,{style:{opacity:1}})
// 元素居中
this.graph.focusItem(ev.item)
// 高亮关联线及节点
this.graph.getEdges().forEach(edge=>{if(edge.getSouce() === ev.item){this.graph.updateItem(edge.getTarget(),{style:{opacity:1}})
this.graph.updateItem(edge,{style:{opacity:1}})
edge.toFront()}else if(edge.getTarget() === ev.item){this.graph.updateItem(edge.getSouce(),{style:{opacity:1}})
this.graph.updateItem(edge,{style:{opacity:1}})
edge.toFront()}else{this.graph.updateItem(edge,{style:{opacity:0.2}})
}
})
})
点击空白处,革除标记状态
this.graph.on("canvas:click",()=>{this.graph.getNodes().forEach(node=>{if(this.positionId){
// 设置所有元素透明度 0.2
this.graph.updateItem(node,{style:{opacity:0.2}})
}
this.graph.clearItemStatus(node)
})
this.graph.getEdges().forEach(edge=>{if(this.positionId){
// 关联线 0.2
this.graph.updateItem(edge,{style:{opacity:0.2}})
}
this.graph.clearItemStatus(edge)
})
})