vue+d3v6实现动态知识图谱可视化展示

目录

  • 一、前言
  • 二、d3@v6相关链接参考
  • 三、代码详细介绍
    • 1. 页面结构(2021年5月更新)
    • 2. 代码结构(2021年5月新增)
    • 3. 功能及代码介绍
      • 1)d3初始化(2021年5月更新)
      • 2)图查询更新视图(2021年5月更新)
      • 3)平移与缩放(2021年5月更新)
      • 4)文字显示
      • 5)拖拽
      • 6)鼠标浮动事件(2021年5月更新)
      • 7)鼠标单击事件(2021年5月更新)
      • 8)鼠标右键菜单(写一个d3插件)
      • 9)图例交互事件
      • 10)文字搜索(2021年5月更新)
      • 11)模式选择(2021年5月更新)
      • 12)关系文字和箭头的绘制与调整(2021年5月新增)
      • 13)节点编辑功能(2021年5月新增)
      • 14)3D图谱展示(2021年5月新增)
  • 四、个人代码参考
  • 五、总结

一、前言

之前的博客:对Neo4j导出数据做知识图谱可视化 D3库实现

之前博客做的知识图谱可视化只是在html上直接写的页面,而且d3还使用的是v4版本的库。

但是当项目复杂的情况下(前端项目越来越复杂了),比如要在系统中加入其他图表进行综合大屏展示,显然不是一个很好的选择,于是决定用vue重构一下代码,把图可视化作为一个组件来维护,顺便再用一下新版本的d3。同时之前的项目存在一个致命的问题,就是动态更新,即当页面已经有图谱展示的情况下,查询新的数据时,无法正常展示(节点全跑到左上角去了)

下图是向基于nodejs搭建neo4j后端服务请求数据后,更新视图出现的问题:(Vue重构后,代码不变的情况下可以解决该问题)

vue+d3v6实现动态知识图谱可视化展示_第1张图片

二、d3@v6相关链接参考

下面附上供学习和参考的链接:

  • D3官方网站
  • D3 npm包地址
  • D3学习文档
  • D3 Tutorials
  • D3 Graph Theory
  • D3新版本改动官方说明文档
  • D3 案例参考
  • 官方力导向图DEMO参考(svg)
  • 官方力导向图DEMO参考(canvas)
  • 右键事件绑定DEMO
  • github关于右键菜单的插件库参考

目前d3已经到v6版本了(更新是真滴快),关于新版d3的改动说明的链接我放在了上面供参考。虽然更新了很多东西,但总的来说原来的代码其实改动不大,比如新版的d3移除了d3.eventv4版本需要注意。

三、代码详细介绍

1. 页面结构(2021年5月更新)

首先页面的整体结构如下,分为2D和3D图谱展示两个页面,其中2D知识图谱除了展示还实现了各种图交互功能;而3D知识图谱采用了第三方模块,底层使用 D3+Three 实现视图渲染,直接截图展示:
vue+d3v6实现动态知识图谱可视化展示_第2张图片

2. 代码结构(2021年5月新增)

这次对代码结构作了大改,变化挺大的,文件夹对应关系如下:

  • 组件存放在 components 文件夹
    • d3graph.vue —— 2D图谱展示组件
    • threeGraph.vue —— 3D图谱展示组件
    • gSearch.vue —— 搜索组件,目前主要通过require代替后台请求
  • 页面存放在 views 文件夹
    • 2dView.vue —— 2D图谱展示页面
    • 3dView.vue —— 3D图谱展示页面
  • d3插件存放在 plugins 文件夹
    • d3-context-menu.js —— 右键菜单事件注册及回调函数
    • d3-context-menu.scss —— 右键菜单样式文件
  • 路由存放在 router 文件夹
    • index.js —— 路由较少,就2个页面
  • 静态图数据存放在 data 文件夹
  • storeassets 文件夹暂时不用

3. 功能及代码介绍

接下来介绍关于图可视化的基本功能与交互事件:

1)d3初始化(2021年5月更新)

d3初始化,包括数据解析、数据渲染及响应式数据初始化,在新版本代码将数据解析分离出来,放到 2dView.vue 页面中 。现在d3初始化分为数据渲染和状态初始化两个任务。

旧版本:

// d3初始化,包括数据解析、数据渲染
d3init () {
   
  // this.graph存放json数据
  this.d3jsonParser(this.graph)
  this.d3render()
  // 数据初始化(节点状态)
  this.nodeState = 0
  this.states = ['on', 'on', 'on', 'on']
}

新版本:

// d3初始化,包括数据解析、数据渲染
d3init () {
   
  this.links = this.data.links
  this.nodes = this.data.nodes
  this.svgDom = d3.select('#svg')  // 获取svg的DOM元素
  // this.d3jsonParser(this.graph)
  this.d3render()
  // 数据状态初始化
  this.stateInit()
},
  • d3jsonParser:对请求的json数据进行解析,分别格式化为节点和关系数据,解析后存放到 this.links(关系显示数据) / this.nodes(节点显示数据) / this.data(全部图数据)
d3jsonParser (json) {
   
  const nodes =[]
  const links = [] // 存放节点和关系
  const nodeSet = [] // 存放去重后nodes的id

  // 使用vue直接通过require获取本地json,不再需要使用d3.json获取数据
  // d3.json('./../data/records.json', function (error, data) {
   
  //   if (error) throw error
  //   graph = data
  //   console.log(graph[0].p)
  // })

  for (let item of json) {
   
    for (let segment of item.p.segments) {
   
      // 重新更改data格式
      if (nodeSet.indexOf(segment.start.identity) == -1) {
   
        nodeSet.push(segment.start.identity)
        nodes.push({
   
          id: segment.start.identity,
          label: segment.start.labels[0],
          properties: segment.start.properties
        })
      }
      if (nodeSet.indexOf(segment.end.identity) == -1) {
   
        nodeSet.push(segment.end.identity)
        nodes.push({
   
          id: segment.end.identity,
          label: segment.end.labels[0],
          properties: segment.end.properties
        })
      }
      links.push({
   
        source: segment.relationship.start,
        target: segment.relationship.end,
        type: segment.relationship.type,
        properties: segment.relationship.properties
      })
    }
  }
  console.log(nodes)
  console.log(links)
  this.links = links
  this.nodes = nodes
  this.data = {
    nodes, links }
  // return { nodes, links }
}
  • d3render代码部分较多,包括了DOM挂载、事件绑定、以及D3视图渲染,在下面一一进行介绍

2)图查询更新视图(2021年5月更新)

该按钮模拟了向后台请求数据的功能,获取新的数据后,更新图展示部分,重新渲染视图,解决了原博客在动态更新这一块的问题。

在这里插入图片描述
旧版(暂时保留图片):
vue+d3v6实现动态知识图谱可视化展示_第3张图片

目前查询暂用require本地数据代替后台请求数据,gSearch.vue 将数据传给页面,并执行数据解析的任务;而 d3graph.vue 组件通过 watch 监听当前的数据变化,更新后通过 this.d3init() 重新渲染页面。

gSearch.vue 模拟后台查询:

query () {
   
  // console.log(typeof this.mode)
  if (this.data.length <= 20) {
   
    this.data = require('../data/top5.json')
  } else {
   
    this.data = require('../data/records.json')
  }
  this.$emit('getData', this.data)
}

d3graph.vue 监听数据变化:

watch: {
   
  // 当请求到新的数据时,重新渲染
  data (newData, oldData) {
   
    console.log(newData, oldData)
    // 移除svg和元素注册事件,防止内存泄漏
    this.svgDom.on('.', null)
    this.svgDom.selectAll('*').on('.', null)
    this.d3init()
  }
}

3)平移与缩放(2021年5月更新)

  • 按住鼠标在空白位置移动可以移动视图的相对位置
  • 鼠标滚轮完成视图的放大和缩小

下图展示将视图通过缩放、拖拽和平移来调整图谱布局,使展示结果更加清晰。
vue+d3v6实现动态知识图谱可视化展示_第4张图片

事件直接在svg视图部分注册,通过标签的translate和scale属性实现平移和缩放:

var svg = d3.select("#svg1")
  // 给画布绑定zoom事件(缩放、平移)
  .call(d3.zoom().on('zoom', function(event) {
   
    // console.log(event)
    var scale = event.transform.k,
        translate = [event.transform.x, event.transform.y]

	// 视图矫正,暂不使用
    // if (this.svgTranslate) {
   
    //     translate[0] += t

你可能感兴趣的:(前端可视化,Vue,知识图谱,知识图谱,vue,d3.js)