relation-graph实现图谱功能

<template>
  <div  class="container">
    <div  ref="myPage" style="height:calc(75vh);"  >
      <div class="flex ">
        <ul class="color-list">
          <li>
            <a href="#">
              <span class="color-block policy"></span>
              政策文件
            </a>
          </li>
          <li>
            <a href="#">
              <span class="color-block application"></span>
              申报通知
            </a>
          </li>
          <li>
            <a href="#">
              <span class="color-block support"></span>
              扶持项目
            </a>
          </li>
          <li>
            <a href="#">
              <span class="color-block announcement"></span>
              公示公告
            </a>
          </li>
        </ul>
      </div>
      <RelationGraph
        ref="graphRef"
        :options="graphOptions"
        :on-node-click="onNodeClick"
        :on-line-click="onLineClick"
        :on-canvas-click="onCanvasClick"
      >

        <template #node="{node}">
          <div @mouseover="showNodeTips(node, $event)" @mouseout="hideNodeTips(node, $event)">
            <el-popover
              placement="top-start" title="" width="310" trigger="hover" content="">
              <div class="custom-title" ><el-button size="mini" class="graph_button"   @click="handlePreview(node.data)">{{node.data.title}}</el-button>
              </div>
              <p style="font-size: 13px;margin-left: 5px"><span v-show="node.data.type===4">发文日期:</span><span v-show="node.data.type!==4">截止日期:</span>&nbsp;{{node.data.publishTime}}</p>
              <div
                slot="reference"
                class="zhengce_content"
              >
                <span v-if="node.data.title.length>20">{{ node.data.title.substr(0,20) }}...</span>
                <span v-else>{{ node.data.title}}</span>
              </div>
            </el-popover>

            <!--            <div-->
            <!--              slot="reference"-->
            <!--              style="color: #fff;-->
            <!--                  width: 100px;-->
            <!--                  height: 100px;-->
            <!--                  border-radius: 50%;-->
            <!--                  font-size: 14px;position: absolute;-->
            <!--                  line-height: 15px;-->
            <!--                  text-align: center;-->
            <!--                  align-items: center;-->
            <!--                   display: flex;-->
            <!--                  justify-content: center;-->
            <!--                 "-->
            <!--            >-->
            <!--              <span v-if="node.data.title.length>20">{{ node.data.title.substr(0,20) }}...</span>-->
            <!--              <span v-else>{{ node.data.title}}</span>-->
            <!--            </div>-->
          </div>
        </template>
      </RelationGraph>
      <!--      <div v-if="isShowNodeTipsPanel" :style="{left: nodeMenuPanelPosition.x + 'px', top: nodeMenuPanelPosition.y + 'px' }"-->
      <!--           style="z-index: 999;padding:10px;background-color: #ffffff;border:#eeeeee solid 1px;box-shadow: 0px 0px 8px #cccccc;position: absolute;">-->
      <!--        <div class="custom-title" >-->
      <!--          <el-button size="mini" class="graph_button"   @click="handlePreview(currentNode.data)">{{currentNode.data.title}}-->
      <!--          </el-button>-->
      <!--        </div>-->
      <!--        <p style="font-size: 13px;margin-left: 5px"><span v-show="currentNode.data.type===4">发文日期:</span>-->
      <!--          <span v-show="currentNode.data.type!==4">截止日期:</span>-->
      <!--          &nbsp;{{currentNode.data.publishTime}}</p>-->
      <!--      </div>-->
    </div>
  </div>
</template>

<script>
// 如果您没有在main.js文件中使用Vue.use(RelationGraph); 就需要使用下面这一行代码来引入relation-graph
import RelationGraph from 'relation-graph';
export default {
  name: 'ZhengceGraph',
  components: { RelationGraph},
  data() {
    return {
      isShowCodePanel: false,
      isShowNodeTipsPanel:false,
      nodeMenuPanelPosition: { x: 0, y: 0 },
      currentNode: {},
      graphOptions: {
        defaultFocusRootNode:false,
        moveToCenterWhenRefresh: false,
        zoomToFitWhenRefresh: false,
        layout: {
          label: "中心",
          layoutName: "force",
          centerOffset_x: 0,
          centerOffset_y: 0,
          distance_coefficient: 0.5,
          maxLayoutTimes: 300,
          force_node_repulsion: 1,
          force_line_elastic: 1
        }
      },
    };
  },
  props:{
    rootId:{
      type:Number,
      default:''
    },
    nodes:{
      type:Array,
      default:[]
    },
    lines:{
      type:Array,
      default:[]
    },
  },
  mounted() {
    this.showGraph();
  },
  beforeDestroy() {
  },
  created() {

  },
  methods: {

    onCanvasClick($event){
      const allLinks = this.$refs.graphRef.getLinks();
      const allNodes = this.$refs.graphRef.getNodes();
      allNodes.forEach(node=>{
        node.opacity = 1;
      })
      allLinks.forEach(link =>{
        link.relations.forEach(line => {
          line.lineWidth = 1;
          line.opacity= 1;
        });
      })
      // this.$refs.graphRef.focusNodeById(nodeObject.id)
      this.$refs.graphRef.getInstance().dataUpdated();
      this.$forceUpdate();
    },
    handlePreview(data){
      if (data.type===1) {
        window.open(
          process.env.VUE_APP_HOST + `faguidetails/tongzhi/${this.params_city}?id=` + data.zhengceId
        );
      } else if (data.type === 2) {
        window.open(
          process.env.VUE_APP_HOST +
          `formaldetails/tongzhi/${this.params_city}?id=` +
          data.zhengceId +
          "&preview=" +
          "1"
        );
      } else if(data.type===3){
        window.open(process.env.VUE_APP_HOST + `formaldetails/jiedu/${this.params_city}/` + data.zhengceId + '?id=' + data.zhengceId + '&inputId=' + data.projectId + '&preview=' + '1')
      } else if(data.type===4){
        window.open(process.env.VUE_APP_HOST + `publicitydetails/original/${this.params_city}?id=` + data.zhengceId + '&preview=' + '1')
      }
    },
    showGraph() {
      const __graph_json_data = {
        // rootId: this.rootId,
        nodes: this.nodes,
        lines: this.lines,
      };
      this.$refs.graphRef.setJsonData(__graph_json_data, (graphInstance) => {
        // 这些写上当图谱初始化完成后需要执行的代码
      });
    },

    onNodeClick(nodeObject, $event) {
      let noData = nodeObject.data;
      this.nodeData = [];

      for (let key in noData) {
        console.log(key, noData[key]);
        this.nodeData.push({
          0: key,
          1: noData[key]
        });
      }
      const xsids =[nodeObject.id]
      this.lines.filter((item)=>{
        if(item.from === nodeObject.id){
          xsids.push(item.to)
        }
        if(item.to === nodeObject.id ){
          xsids.push(item.from)
        }
      })
      this.userData = nodeObject;
      const allLinks = this.$refs.graphRef.getLinks();
      const allNodes = this.$refs.graphRef.getNodes();
      allNodes.forEach(node=>{
        if (xsids.includes(node.id)) {
          node.opacity = 1;
        }else{
          node.opacity = 0.1;
        }
      })
      allLinks.forEach(link =>{
        if (link.fromNode === nodeObject || link.toNode === nodeObject){
          link.relations.forEach(line => {
            line.lineWidth = 2;
            line.opacity= 1;
          });
        }else{
          link.relations.forEach(line => {
            line.opacity= 0.2;
            line.lineWidth = 1;
          });
        }
      })
      // this.$refs.graphRef.focusNodeById(nodeObject.id)
      this.$refs.graphRef.getInstance().dataUpdated();
      this.$forceUpdate();
    },
    onLineClick(lineObject, linkObject, $event) {
      console.log('onLineClick:', lineObject);
    },
    showNodeTips(nodeObject, $event) {
      console.log("nodeObject==>",nodeObject)
      console.log("$event==>",$event)
      // this.currentNode = nodeObject;
      // const _base_position = this.$refs.myPage.getBoundingClientRect();
      // console.log('showNodeMenus:', $event.clientX, $event.clientY, _base_position);
      // this.isShowNodeTipsPanel = true;
      // this.nodeMenuPanelPosition.x = $event.clientX - _base_position.x + 10;
      // this.nodeMenuPanelPosition.y = $event.clientY - _base_position.y + 10;
    },
    hideNodeTips(nodeObject, $event) {

    },

  }
};
</script>

<style lang="scss">

</style>

<style lang="scss" scoped>
.c-surround-menu-panel{
  position:absolute;width:160px;height:160px;z-index:999;
  animation: growUp 0.8s linear;
}
.node_class{
  text-align: center;
}
.graph_button:hover{
  color: #3078F0;
}
.graph_button {
  width: 275px;
  margin-left: -10px;
  text-align: left;
  word-wrap: break-word;
  overflow-wrap: break-word;
  white-space: normal;
  height: auto;
  overflow: hidden;
  border: none;
  background: #fff;
  box-shadow: none;
  font-size: 15px;
  line-height: 1.2;
  color: #303538;
  font-weight: bold;
}
.color-list {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.color-list li {
  padding: 3px 0;
}

.color-list a {
  text-decoration: none;
  color: inherit;
}
.color-list .color-block {
  display: inline-block;
  width: 20px;
  height: 20px;
  margin-right: 10px;
  vertical-align: middle;
}

.policy { background-color: rgba(2, 167, 240, 1); } /* 蓝色 */
.application { background-color: rgba(112, 182, 3, 1); } /* 粉红色 */
.support { background-color: rgba(236, 128, 141, 1); } /* 绿色 */
.announcement { background-color: rgba(191, 191, 0, 1); } /* 黄色 */
.flex{
  position: absolute;
  top: 50px;
  left: 10px;
  z-index: 1000; /* 确保覆盖其他内容 */
}
.zhengce_content{
  color: #fff; width: 100px;
  height: 100px;
  border-radius: 50%;
  font-size: 14px;position: absolute;
  line-height: 15px;
  text-align: center;
  align-items: center;
  display: flex;
  justify-content: center;
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3 Relation Graph 是一个基于 Vue3 和 D3.js 的关系图谱组件库,可以用于展示和操作复杂的关系网络数据。它提供了丰富的功能和交互效果,其中包括实现线条悬浮框的功能。 要实现线条悬浮框,你可以按照以下步骤进行操作: 1. 安装依赖:首先,在你的 Vue 项目中安装 vue3-relation-graph 组件库。可以使用 npm 或者 yarn 进行安装。 2. 导入组件:在需要使用关系图谱的组件中,导入 vue3-relation-graph 组件。 ```javascript import { RelationGraph } from 'vue3-relation-graph'; ``` 3. 准备数据:准备好你的关系网络数据,包括节点和边的信息。可以根据你的需求,将数据存储在组件的 data 中或者从后端获取。 4. 使用组件:在模板中使用 RelationGraph 组件,并将准备好的数据传递给组件。 ```html <template> <RelationGraph :nodes="nodes" :edges="edges" /> </template> ``` 5. 自定义线条悬浮框:通过配置 RelationGraph 组件的 props,你可以自定义线条悬浮框的内容和样式。可以使用 slot 来自定义线条悬浮框的内容。 ```html <template> <RelationGraph :nodes="nodes" :edges="edges"> <template #edge-tooltip="{ edge }"> <div class="tooltip"> <p>{{ edge.label }}</p> <p>{{ edge.weight }}</p> </div> </template> </RelationGraph> </template> ``` 在上面的例子中,我们使用了一个名为 `edge-tooltip` 的 slot 来自定义线条悬浮框的内容。在这个 slot 中,我们可以访问到当前悬浮的边的信息,并根据需要进行展示。 这样,当用户将鼠标悬停在关系图谱的线条上时,就会显示自定义的线条悬浮框。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值