Logo
技术 转载 C#

vue2.x使用Relation Graph 人物关系图谱

photo
Pastore Antonio

2023年11月08日

贴个官网: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>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <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>
 

效果如下

本文为原创文章,请注意保留出处!
centos 常见问题 2023年11月08日

1:DNS配置 域名无法在Linux下解析是一个比较普遍的问题,造成这个问题有很多原因,比如:服务器 ... centos 常见问题

修复群晖Synology Drive client右键菜单缺失问题 Local, clean & environmental 作者:Pastore Antonio
1806 浏览量
1780 浏览量
configure: error: Package requirements (oniguruma) were not met Local, clean & environmental 作者:Pastore Antonio
1525 浏览量
Adobe Acrobat Pro 激活 Local, clean & environmental 作者:Pastore Antonio
1520 浏览量
追寻日出,找回自己 Local, clean & environmental 作者:Pastore Antonio
1489 浏览量