<template>
<div
v-if="reRender"
id="container"
v-loading="loading"
:element-loading-text="$t('public.please_wait')"
element-loading-spinner="el-icon-loading"
/>
</div>
</template>
<script>
import G6 from "@antv/g6";
import { getTopology } from "@/api/getTopology";
export default {
data() {
return {
reRender: true,
loading: false,
};
},
watch: {
// 切換到其他拓撲圖時重新渲染
$route(n) {
this.reRender = false;
this.$nextTick(() => {
this.reRender = true;
});
this.getData(n.query.id);
},
},
mounted() {
this.$nextTick(() => {
this.getData(this.$route.query.id);
});
},
methods: {
async getData(id) {
// 自定義節點
G6.registerNode(
// 自定義節點名稱
"rect-auto",
{
draw(cfg, group) {
const { label, style } = cfg;
// 畫一個默認矩形
const rect = group.addShape("rect", {
attrs: {
width: 1,
height: 1,
x: 0,
y: 0,
radius: 4,
lineWidth: 1,
stroke: "#409eff",
fill: "#f0f7ff",
// 來自實例配置defaultNode選項的style
...style,
},
name: "rect-shape",
});
// 畫一個文本
const text = group.addShape("text", {
attrs: {
x: 0,
y: 0,
text: label,
textAlign: "left",
textBaseline: "middle",
...style,
...style.labelCfg.style,
},
name: "text-shape",
});
const labelBox = text.getBBox();
// 矩形左右留白各10px,上下留白各6px
rect.attr({
width: labelBox.width + 20,
height: labelBox.height + 12,
});
// 文本位置,以矩形左上角為原點
text.attr({
x: 10,
y: labelBox.height / 2 + 6,
});
// 返回該矩形
return rect;
},
},
// 繼承自已有rect圖形
"rect"
);
this.loading = true;
// 后端返回標準的數據格式
const res = await getTopology(id);
const data = res.data;
const container = document.getElementById("container");
const width = container.scrollWidth;
const height = container.scrollHeight || 500;
// 實例配置,搜索關鍵字查看具體釋義
const graph = new G6.Graph({
container: "container",
width,
height,
controlPoints: false,
fitView: true,
fitViewPadding: 10,
modes: {
default: [
{
type: "activate-relations",
trigger: "click",
activeState: "active",
inactiveState: "inactive",
},
{
type: "zoom-canvas",
},
{
type: "drag-canvas",
},
{
type: "click-select",
},
],
},
layout: {
type: "dagre",
preventOverlap: true,
nodeSize: 100,
nodesep: 50,
ranksep: 10,
},
animate: true,
defaultNode: {
type: "rect-auto",
anchorPoints: [
[0.5, 0],
[0.5, 1],
],
style: {
cursor: "pointer",
labelCfg: {
style: {
fill: "#000",
},
},
},
},
defaultEdge: {
size: 1,
color: "#ccc",
type: "line",
style: {
endArrow: {
path: G6.Arrow.triangle(6, 6, 0),
// path: "M 0,0 L 8,4 L 8,-4 Z",
fill: "#ccc",
},
},
},
nodeStateStyles: {
active: {
fill: "#fff",
stroke: "#409eff",
lineWidth: 1,
shadowColor: "#409eff",
shadowBlur: 10,
shadowOffsetX: 1,
shadowOffsetY: 1,
"text-shape": {
fill: "#000",
},
},
inactive: {
opacity: 0.6,
},
hover: {
fill: "#fff",
lineWidth: 1,
stroke: "#409eff",
shadowColor: "#409eff",
shadowBlur: 10,
shadowOffsetX: 1,
shadowOffsetY: 1,
"text-shape": {
fill: "#000",
},
},
selected: {
fill: "#fff",
lineWidth: 1,
stroke: "#f56c6c",
shadowColor: "#f56c6c",
shadowBlur: 10,
shadowOffsetX: 1,
shadowOffsetY: 1,
"text-shape": {
fill: "#000",
},
},
},
edgeStateStyles: {
active: {
stroke: "#409eff",
endArrow: {
path: G6.Arrow.triangle(6, 6, 0),
fill: "#409eff",
},
},
inactive: {
opacity: 0.6,
endArrow: {
path: G6.Arrow.triangle(6, 6, 0),
fill: "#ccc",
opacity: 0.6,
},
},
},
});
graph.data(data);
graph.render();
// 節點只有一個時太大,縮放一下
graph.on("afterrender", () => {
if (data.nodes.length === 1) {
graph.zoom(0.2, { x: width / 2, y: height / 2 });
}
});
// 雙擊節點進行跳轉
graph.on("dblclick", (evt) => {
const itemData = evt.item._cfg.model;
const { level, id } = itemData;
this.$emit("changeState", [id]);
if (level === 2) {
this.$router.push({
name: "groupDetail",
query: {
id,
},
});
} else if (level === 3) {
this.$router.push({
name: "serviceInfo",
query: {
id,
},
});
}
});
// 觸發hover樣式配置
graph.on("node:mouseenter", (evt) => {
const { item } = evt;
graph.setItemState(item, "hover", true);
});
// 關閉hover樣式
graph.on("node:mouseleave", (evt) => {
const { item } = evt;
graph.setItemState(item, "hover", false);
});
this.$nextTick(() => {
this.loading = false;
});
if (typeof window !== "undefined") {
window.onresize = () => {
if (!graph || graph.get("destroyed")) return;
if (!container || !container.scrollWidth || !container.scrollHeight)
return;
graph.changeSize(container.scrollWidth, container.scrollHeight - 30);
};
}
},
},
};
</script>
<style lang="scss" scoped>
#container {
height: calc(100vh - 310px);
}
</style>
G6自定義節點樣式配置
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
推薦閱讀更多精彩內容
- 0 場景描述 一個自定義節點,利用 draw 繪制了含有多shape(如:rect,text,image) 的g...
- 背景 最近用Antv-g6做樹圖開發時,需要做滾動的表格,查了g6的文檔,發現沒有滾動,只能自己來做了。主要思路是...
- 在G6 API搜索 ,如下: 例子如下,寫法 再補充一個 就是g6 可以改變node、edge、combo的優先級...
- 既然Actuator給我們內置提供了節點映射,我們為什么還需要進行修改呢? 正因為如此我們才需要進行修改?。?! 路...
- NRD Studio中每個節點和每條關系都支持自定義樣式。 兩個編輯面板中最下方有【應用至全部】,這僅是將當前樣式...