贴个官网:relation-graph:一个vue关系图谱组件
引入relation-graph
npm install --save relation-graph
1.人物关系图谱的基础使用
<template>
<div>
<div
style="
margin-top: 50px;
width: calc(100% - 10px);
height: calc(100vh - 140px);
"
>
<SeeksRelationGraph ref="seeksRelationGraph" :options="graphOptions" />
</div>
</div>
</template>
<script>
import SeeksRelationGraph from "relation-graph";
export default {
name: "SeeksRelationGraphDemo",
components: { SeeksRelationGraph },
data() {
return {
g_loading: true,
demoname: "---",
graphOptions: {
defaultNodeBorderWidth: 0,
defaultNodeColor: "rgba(238, 178, 94, 1)",
allowSwitchLineShape: true,
allowSwitchJunctionPoint: true,
defaultLineShape: 1,
layouts: [
{
label: "自动布局",
layoutName: "force",
layoutClassName: "seeks-layout-force",
},
],
defaultJunctionPoint: "border",
},
};
},
created() {},
mounted() {
this.demoname = this.$route.params.demoname;
this.setGraphData();
},
methods: {
setGraphData() {
var __graph_json_data = {
rootId: "N1",
nodes: [
{
id: "N1",
text: "侯亮平",
data: { isGoodMan: true, sexType: "男", id: "1" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2308340537,462224207&fm=58&app=83&f=JPEG?w=250&h=250&s=EC708F46DA96B89CB69D5DDA0300D014);border:#ff875e solid 3px;"><div class="c-node-name" style="color:#ff875e">侯亮平</div></div>',
},
{
id: "N2",
text: "李达康",
data: { isGoodMan: true, sexType: "男", id: "2" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2677153550,2207805387&fm=58&app=83&f=JPEG?w=250&h=250&s=249039DDC2D153D411A851360300C062);border:#ff875e solid 3px;"><div class="c-node-name" style="color:#ff875e">李达康</div></div>',
},
{
id: "N3",
text: "祁同伟",
data: { isGoodMan: false, sexType: "男", id: "3" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=1725297532,1915921796&fm=58&app=83&f=JPEG?w=250&h=250&s=FE8EA444A60759554DAC1DBB03000092);border:#6cc0ff solid 3px;"><div class="c-node-name" style="color:#6cc0ff">祁同伟</div></div>',
},
{
id: "N4",
text: "陈岩石",
data: { isGoodMan: true, sexType: "男", id: "4" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2025797948,1615296290&fm=58&app=83&f=JPEG?w=250&h=250&s=B5B04C331F32739C4604F9F503007021);border:#ff875e solid 3px;"><div class="c-node-name" style="color:#ff875e">陈岩石</div></div>',
},
{
id: "N5",
text: "陆亦可",
data: { isGoodMan: true, sexType: "女", id: "5" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=344720653,260255884&fm=58&app=83&f=JPEG?w=250&h=250&s=57B8AB676AE862941D94ED170300E060);border:#ff875e solid 3px;"><div class="c-node-name" style="color:#ff875e">陆亦可</div></div>',
},
],
links: [
{
from: "N1",
to: "N2",
text: "师生",
data: { type: "师生" },
},
{
from: "N1",
to: "N3",
text: "师生",
data: { type: "师生" },
},
{
from: "N1",
to: "N4",
text: "上下级",
data: { type: "上下级" },
},
{
from: "N1",
to: "N5",
text: "亲戚",
data: { type: "亲戚" },
},
],
};
this.$refs.seeksRelationGraph.setJsonData(
__graph_json_data,
(seeksRGGraph) => {
// 这些写上当图谱初始化完成后需要执行的代码
}
);
},
},
};
</script>
<style>
.c-my-node {
background-position: center center;
background-size: 100%;
border: #ff8c00 solid 2px;
height: 80px;
width: 80px;
border-radius: 40px;
}
.c-node-name {
width: 160px;
margin-left: -40px;
text-align: center;
margin-top: 85px;
}
</style>
注:上述graphOptions中配置中,当相互关系人少于5条时,会造成相互关系的连线造成遮掩等问题,如下图所示
这时graphOptions配置修改如下即可不存在遮掩
graphOptions: {
useLayoutStyleOptions: true,
defaultNodeBorderWidth: 0,
defaultLineShape: 1,
defaultNodeColor: "gary",
defaultNodeFontColor: "rgba(51,51,51,1)",
allowSwitchLineShape: true,
allowSwitchJunctionPoint: true,
layouts: [
{
label: "中心",
layoutName: "center",
layoutClassName: "seeks-layout-center",
distance_coefficient: 0.6,
},
],
defaultJunctionPoint: "border",
},
2.人物关系图包括筛选条件,点击弹出详情的使用,使用element-ui
<template>
<div @click="click">
<div
style="
height: 110px;
padding-top: 6px;
padding-left: 30px;
padding-right: 30px;
border-bottom: #efefef solid 1px;
color: #555555;
font-size: 12px;
"
>
<div style="">
<div style="line-height: 20px">节点筛选:</div>
<el-radio-group v-model="checked_sex" size="mini" @change="doFilter">
<el-radio-button label="">全部</el-radio-button>
<el-radio-button label="男"></el-radio-button>
<el-radio-button label="女"></el-radio-button>
</el-radio-group>
<el-radio-group
v-model="checked_isgoodman"
size="mini"
style="margin-left: 50px"
@change="doFilter"
>
<el-radio-button label="">全部</el-radio-button>
<el-radio-button :label="true">正面人物</el-radio-button>
<el-radio-button :label="false">反面人物</el-radio-button>
</el-radio-group>
</div>
<div>
<div style="line-height: 20px">关系筛选:</div>
<el-checkbox-group v-model="rel_checkList" @change="doFilter">
<el-checkbox
v-for="thisItem in all_rel_type"
:key="thisItem"
:label="thisItem"
/>
</el-checkbox-group>
</div>
</div>
<div class="seeksrelationgraph">
<el-popover
width="200"
trigger="manual"
v-model="visible"
class="seek_popover_style"
:style="{ left: position.left + 'px', top: position.top + 'px' }"
>
<template>
<el-form :model="fromData" label-width="80px">
<el-form-item
class="relationship_item"
label="曾用名:"
prop="name"
>
{{ filterEmpty(fromData.text) }}
</el-form-item>
<el-form-item
class="relationship_item"
label="性别:"
prop="sexType"
>
{{ filterEmpty(fromData.sexType) }}
</el-form-item>
<el-form-item
class="relationship_item"
label="其他:"
prop="sexType"
>
{{ filterEmpty(fromData.name) }}
</el-form-item>
</el-form>
</template>
</el-popover>
<SeeksRelationGraph
ref="seeksRelationGraph"
:options="graphOptions"
:graph-setting="graphSetting"
:on-node-click="onNodeClick"
:on-line-click="onLineClick"
/>
</div>
</div>
</template>
<script>
import SeeksRelationGraph from "relation-graph";
export default {
name: "SeeksRelationGraphDemo",
components: { SeeksRelationGraph },
data() {
return {
fromData: {},
position: {
left: 100,
top: 100,
},
visible: false,
g_loading: true,
demoname: "---",
checked_sex: "",
checked_isgoodman: "",
rel_checkList: [
"师生",
"上下级",
"亲戚",
"情人",
"朋友",
"夫妻",
"勾结",
"腐化",
"举报",
],
all_rel_type: [
"师生",
"上下级",
"亲戚",
"情人",
"朋友",
"夫妻",
"勾结",
"腐化",
"举报",
],
graphOptions: {
useLayoutStyleOptions: true,
defaultNodeBorderWidth: 0,
defaultLineShape: 1,
defaultNodeColor: "gary",
defaultNodeFontColor: "rgba(51,51,51,1)",
allowSwitchLineShape: true,
allowSwitchJunctionPoint: true,
layouts: [
{
label: "中心",
layoutName: "center",
layoutClassName: "seeks-layout-center",
distance_coefficient: 0.6,
},
],
defaultJunctionPoint: "border",
},
};
},
mounted() {
this.setGraphData();
},
methods: {
filterEmpty(data) {
return data ? data : "--";
},
setGraphData() {
var __graph_json_data = {
rootId: "N1",
nodes: [
{
id: "N1",
text: "侯亮平",
data: { isGoodMan: true, sexType: "男", id: "1", text: "侯亮平" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2308340537,462224207&fm=58&app=83&f=JPEG?w=250&h=250&s=EC708F46DA96B89CB69D5DDA0300D014);border:#ff875e solid 3px;"><div class="c-node-name" style="color:#ff875e">侯亮平</div></div>',
},
{
id: "N2",
text: "李达康",
data: { isGoodMan: true, sexType: "男", id: "2", text: "李达康" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2677153550,2207805387&fm=58&app=83&f=JPEG?w=250&h=250&s=249039DDC2D153D411A851360300C062);border:#ff875e solid 3px;"><div class="c-node-name" style="color:#ff875e">李达康</div></div>',
},
{
id: "N3",
text: "祁同伟",
data: { isGoodMan: false, sexType: "男", id: "3", text: "祁同伟" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=1725297532,1915921796&fm=58&app=83&f=JPEG?w=250&h=250&s=FE8EA444A60759554DAC1DBB03000092);border:#6cc0ff solid 3px;"><div class="c-node-name" style="color:#6cc0ff">祁同伟</div></div>',
},
{
id: "N4",
text: "陈岩石",
data: { isGoodMan: true, sexType: "女", id: "4", text: "陈岩石" },
innerHTML:
'<div class="c-my-node" style="background-image: url(https://dss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=2025797948,1615296290&fm=58&app=83&f=JPEG?w=250&h=250&s=B5B04C331F32739C4604F9F503007021);border:#ff875e solid 3px;"><div class="c-node-name" style="color:#ff875e">陈岩石</div></div>',
},
],
links: [
{
from: "N1",
to: "N2",
text: "师生",
data: { type: "师生" },
},
{
from: "N1",
to: "N3",
text: "师生",
data: { type: "师生" },
},
{
from: "N1",
to: "N4",
text: "上下级",
data: { type: "上下级" },
},
{
from: "N1",
to: "N5",
text: "亲戚",
data: { type: "亲戚" },
},
],
};
this.$refs.seeksRelationGraph.setJsonData(
__graph_json_data,
(seeksRGGraph) => {
// 这些写上当图谱初始化完成后需要执行的代码
}
);
},
doFilter() {
console.log("getNodes", this.$refs.seeksRelationGraph.getNodes());
console.log("getLines", this.$refs.seeksRelationGraph.getLines());
var _all_nodes = this.$refs.seeksRelationGraph.getNodes();
var _all_lines = this.$refs.seeksRelationGraph.getLines();
_all_nodes.forEach((thisNode) => {
var _isHideThisLine = false;
if (this.checked_sex !== "") {
if (thisNode.data["sexType"] !== this.checked_sex) {
_isHideThisLine = true;
}
}
if (this.checked_isgoodman !== "") {
if (thisNode.data["isGoodMan"] !== this.checked_isgoodman) {
_isHideThisLine = true;
}
}
thisNode.opacity = _isHideThisLine ? 0.1 : 1;
});
_all_lines.forEach((thisLine) => {
// 注意这里的line和json数据中link不一样,一条线(line)上可以附着多条关系(link),可以通过line.relations获取到这条线上所有的关系数据(link)
var _isHideThisLine = true;
thisLine.relations.forEach((thisLink) => {
if (this.rel_checkList.indexOf(thisLink.data["type"]) === -1) {
thisLink.isHide = true;
} else {
_isHideThisLine = false;
thisLink.isHide = false;
}
});
// thisNode.opacity = _isShowThisNode ? 1 : 0.1
});
},
//全局点击事件
click() {
if (this.visible) this.visible = !this.visible;
},
// nodeObject 返回的是节点当中data内的数据
onNodeClick(nodeObject, $event) {
console.log("onNodeClick:", nodeObject, "event", $event);
this.position = {
left: $event.x - 150,
top: $event.y - 100,
};
if (this.fromData.id == nodeObject.data.id) {
this.visible = !this.visible;
} else {
this.visible = true;
}
this.fromData = nodeObject.data;
},
// 关系线点击事件
onLineClick(lineObject, $event) {
console.log("onLineClick:", lineObject);
},
graphSetting(graphSetting, $event) {
console.log("graphSetting", graphSetting, "$event", $event);
},
},
};
</script>
<style lang="scss">
.c-my-node {
background-position: center center;
background-size: 100%;
border: #ff8c00 solid 2px;
height: 80px;
width: 80px;
border-radius: 40px;
}
.c-node-name {
width: 160px;
margin-left: -40px;
text-align: center;
margin-top: 85px;
}
.seeksrelationgraph {
margin-top: 0px;
width: calc(100% - 10px);
height: calc(100vh - 200px);
.seek_popover_style {
position: absolute;
}
.relationship_item {
margin-bottom: 0px;
}
}
</style>
效果如下