最近工作需要,用了antv g6绘图,参照了官网的例子
<template>
<div id="container"></div>
</template>
<script>
import { defineComponent, onMounted, ref, watch } from "vue";
import { getKinship } from "@/services/study.js";
import G6 from "@antv/g6";
import { message } from "ant-design-vue";
export default defineComponent({
props: {
selectedId: {
type: Object,
default: null,
},
},
setup(props) {
watch(props, (newProps) => {
if (newProps.selectedId) {
chooseId.value = newProps.selectedId.id;
}
});
const chooseId = ref(props.selectedId.id);
const data = ref([]);
const relations = ref([]);
const graphs = ref(null);
const container = ref();
const resolution = ref(document.documentElement.clientWidth / 1920);
const refresh = () => {
getKinship(chooseId.value).then((res) => {
if (res.data.success) {
relations.value = res.data.data.relations[0];
data.value = res.data.data.tables;
graphs.value.data(relations.value);
graphs.value.render();
// graphs.value.translate(150, 100);
graphs.value.fitCenter(true);
graphs.value.zoom(resolution.value);
} else {
message.error(res.data.msg);
}
});
};
const init = () => {
G6.registerNode("card-node", {
draw: function drawShape(cfg, group) {
const r = 2;
const color = "#5B8FF9";
const w = cfg.size[0];
const h = cfg.size[1];
const shape = group.addShape("rect", {
attrs: {
x: -w / 2,
y: -h / 2,
width: w, //200,
height: 1.5 * h, // 60
stroke: color,
radius: r,
fill: "#fff",
},
name: "main-box",
draggable: true,
});
group.addShape("rect", {
attrs: {
x: -w / 2,
y: -h / 2,
width: w, //200,
height: h / 2, // 60
fill: color,
radius: [r, r, 0, 0],
},
name: "title-box",
draggable: true,
});
// title text
group.addShape("text", {
attrs: {
textBaseline: "top",
x: -w / 2 + 8,
y: -h / 2 + 2,
lineHeight: 20,
text: cfg.name,
fill: "#fff",
},
name: "title",
});
cfg.children &&
group.addShape("marker", {
attrs: {
x: w / 2,
y: 0,
r: 6,
cursor: "pointer",
symbol: cfg.collapsed ? G6.Marker.expand : G6.Marker.collapse,
stroke: "#666",
lineWidth: 1,
fill: "#fff",
},
name: "collapse-icon",
});
group.addShape("text", {
attrs: {
textBaseline: "top",
x: -w / 2 + 8,
y: -h / 2 + 24,
lineHeight: 20,
text: cfg.tips,
fill: "rgba(0,0,0, 1)",
},
name: `description`,
});
return shape;
},
setState(name, value, item) {
if (name === "collapsed") {
const marker = item.get("group").find((ele) => ele.get("name") === "collapse-icon");
const icon = value ? G6.Marker.expand : G6.Marker.collapse;
marker.attr("symbol", icon);
}
},
});
container.value = document.getElementById("container");
const width = container.value.scrollWidth;
const height = container.value.scrollHeight || 500;
graphs.value = new G6.TreeGraph({
container: "container",
width,
height,
modes: {
default: ["drag-canvas"],
},
defaultNode: {
type: "card-node",
size: [225, 40],
},
defaultEdge: {
type: "cubic-horizontal",
style: {
startArrow: true,
},
},
layout: {
type: "indented",
direction: "RL",
dropCap: false,
indent: 275,
getHeight: () => {
return 80;
},
},
});
graphs.value.on("node:click", (e) => {
if (e.target.get("name") === "collapse-icon") {
e.item.getModel().collapsed = !e.item.getModel().collapsed;
graphs.value.setItemState(e.item, "collapsed", e.item.getModel().collapsed);
graphs.value.layout();
}
});
if (typeof window !== "undefined")
window.onresize = () => {
if (!graphs.value || graphs.value.get("destroyed")) return;
if (!container.value || !container.value.scrollWidth || !container.value.scrollHeight) return;
graphs.value.changeSize(container.value.scrollWidth, container.value.scrollHeight);
};
refresh();
};
onMounted(() => {
init();
});
return {
data,
chooseId,
relations,
refresh,
graphs,
container,
resolution,
};
},
});
</script>
<style lang="less" scoped>
#container {
width: 100%;
height: 100%;
padding: 20px;
}
</style>