图数据库Neo4j学习五渲染图数据库neo4jd3
文章目录
- 1.现成的工具
- 2.Neo4j JavaScript Driver
- 3.neovis
- 4.neo4jd3
- 4.1neo4jd3和neovis对比
- 4.2获取neo4jd3
- 4.3neo4jd3的数据结构
- 4.4Spring data neo
- 4.4.1 定义返回数据格式
- 4.4.1.1NeoResults
- 4.4.1.2GraphVO
- 4.4.1.3NodeVO
- 4.4.1.4ShipVO
- 4.4.2 SDN查询解析
- 4.4.2.1 Repo查询语句
- 4.4.2.2 解析Repo查询
- 4.4.2.3返回解析结果
- 4.4.3前端处理渲染
- 4.5实现效果
本文最终技术架构:neo4jd3 + Spring boot + Spring Data Neo + neo4j
当我们刚开是接触图数据库的时候,我们进行各种关系查询,最终会得到一个拓扑图。和我们以前使用的数据库不一样的是,我们的数据库查询出来是一系列的表。

事实上,我们的图数据返回的的数据是类似于下面这样的格式的,然后通过前端(Neo4j Browser )来帮我们将返回的数据绘制成网络拓扑图。在我们之前的文章中介绍的Spring Data Neo中,返回的也都是java对象的数据

接下来本文就是介绍使用一些前端技术来帮我们将图数据库的数据返回给前端进行旋绕
1.现成的工具
比如Neo4j Browser 、Neo4j Bloom、这些官方提供的工具,免费或者有商业版权,这些工具特点都是人家已经开发好的工具,你安装上使用就行了。
例如Neo4j Browser,这些工具就好比,我们Navicat 、Sql Log、PL SQL这些客户端连接工具连接关系型数据库(mysql、oracle、post gre)等。本文就不在详细介绍。

2.Neo4j JavaScript Driver
Neo4j JavaScript Driver 是一个用于在 JavaScript 应用程序中与 Neo4j 图数据库进行通信的官方驱动程序。它提供了与 Neo4j 服务器进行连接、执行 Cypher 查询和处理查询结果等功能。我们可以在Jquery、React、Angular、Vue等前端框架中使用该驱动。
驱动安装
npm install neo4j-driver
代码示例
const neo4j = require('neo4j-driver')
const driver = neo4j.driver(uri, neo4j.auth.basic(user, password))
const session = driver.session()
const personName = 'Alice'try {const result = await session.run('CREATE (a:Person {name: $name}) RETURN a',{ name: personName })const singleRecord = result.records[0]const node = singleRecord.get(0)console.log(node.properties.name)
} finally {await session.close()
}// on application exit:
await driver.close()
官方地址:neo4j-javascript
适用于:前端直接和Neo4J直接连接
3.neovis
Neovis.js 是一个纯 JavaScript 库,使用 JavaScript 语言编写和开发开源框架。它可以在浏览器环境中直接使用,也可以与其他 JavaScript 框架和库集成,如 React、Angular 或 Vue.js
- Neovis.js 使用 Neo4j JavaScript Driver 与 Neo4j 图数据库进行通信。
- Neovis.js 在 Vis.js 的基础上构建了对 Neo4j 数据库的特定集成和功能
github地址:github-neovis.js
下面这是一个官方的示例:

Neovis.js可以通过npm安装
npm install --save neovis.js
Neovis.js可以从Neo4jLabs CDN获得
<script src="https://unpkg.com/neovis.js@2.0.2"></script>
<script src="https://unpkg.com/neovis.js@2.0.2/dist/neovis-without-dependencies.js"></script>
代码示例
需要在代码中定义每个节点,边,例如下乳,查询用户和角色
<script type="text/javascript">let neoViz;function draw() {const config = {containerId: "viz",neo4j: {serverUrl: "bolt://localhost:7687",//neo4j的用户名和密码serverUser: "neo4j",serverPassword: "neo4j",},labels: {//节点的标签1(节点类型:用户)User: {//在User类型的节点上,使用userName作为节点的显示label: "userName"},//节点的标签2(节点类型:角色)Role: {//在Role类型的节点上,使用roleName作为节点的显示label: "roleName",}//节点的标签3.......},relationships: {//关系1(边)PLAY_THE_ROLE: {value: "name"}},//Cypher语句initialCypher: "MATCH (n)-[r:PLAY_THE_ROLE]->(m) RETURN *"};neoViz = new NeoVis.default(config);neoViz.render();}
</script>
4.neo4jd3
neo4jd3使用D3.js实现Neo4j图形可视化。
github地址:githug-neo4jd3,表现效果如下:

4.1neo4jd3和neovis对比
neo4jd3和neovis是两个完全不同的组件,使用方式也不一样。
-
在底层依赖上:
neovis.js 是基于 Vis.js、neo4j JavaScript Driver 构建的,而 neo4jd3.js 基于 D3.js。 -
在功能上:
neovis.js 能够直接和neo4j 数据库相连,将数据库查询结果直接进行渲染,而neo4jd3则不和数据库相连,而是通过数据进行渲染。所以对于neo4jd3来说,只要能提供数据,就能渲染,因此我们可以使用任何技术为neo4jd3来进行获取数据,最后将数据给neo4jd3。 -
在渲染上:
neovis.js侧重于将数据库的查询语句发送给数据,然后渲染数据库返回的结果值,因此在渲染效果上存在很多的不友好一面。而neo4jd3并不关心查询语句如何编写,数据库如何查询,只对最后的数据进行渲染,因此在渲染效果上就体现的非常友好
以下是对同一个数据的查询结果进行的渲染对比,左图是neovis,右图neo4jd3,单从拓扑图上来说,左边的效果就很差

4.2获取neo4jd3
从仓库中下载代码,在dist目录下,有css和js

git clone https://github.com/eisman/neo4jd3.git

4.3neo4jd3的数据结构
我们先看官网给的两组Json,也就是需要我们的数据组织者按照如下格式进行数据格式组织
返回节点和关系的json
{"nodes": [{"id": "1","labels": ["User"],"properties": {"userId": "eisman"}},{"id": "8","labels": ["Project"],"properties": {"name": "neo4jd3","title": "neo4jd3.js","description": "Neo4j graph visualization using D3.js.","url": "https://eisman.github.io/neo4jd3"}}],"relationships": [{"id": "7","type": "DEVELOPES","startNode": "1","endNode": "8","properties": {"from": 1470002400000},"source": "1","target": "8","linknum": 1}]
}
返回绘制图的Json
{"results": [{"columns": ["user", "entity"],"data": [{"graph": {"nodes": [{"id": "1","labels": ["User"],"properties": {"userId": "eisman"}},{"id": "8","labels": ["Project"],"properties": {"name": "neo4jd3","title": "neo4jd3.js","description": "Neo4j graph visualization using D3.js.","url": "https://eisman.github.io/neo4jd3"}}],"relationships": [{"id": "7","type": "DEVELOPES","startNode": "1","endNode": "8","properties": {"from": 1470002400000}}]}}]}],"errors": []
}
4.4Spring data neo
我们现在已经知道了neo4jd3绘制图的Json格式了,现在就需要我们后台查询数据,然后返回
4.4.1 定义返回数据格式

我们当然也能通过数据格式发现,嵌套有点深,这里推荐按照这个格式来,因为不这样的话,你就得要求修改前端组建的源代码了。下面这个是前端渲染数据的一部分代码,如果后端返回的数据不按照这个格式来的话,前端这里就需要你修改代码了。

这里我避免创建很多单一属性的类,因此采用了内部类的方式,这里你不一定才用内部类,只要能返回和上面的Json格式就行
4.4.1.1NeoResults
@lombok.Data
public class NeoResults {private List<Data> results = new ArrayList<>();public NeoResults() {super();results.add(new NeoResults.Data());}@lombok.Datapublic class Data{private List<Graph> data = new ArrayList<>();public Data() {super();data.add(new Data.Graph());}@lombok.Datapublic class Graph{private GraphVO graph = new GraphVO();}}public void setNodes(List<NodeVO> nodes) {results.get(0).getData().get(0).getGraph().setNodes(nodes);} public void setRelationships(List<ShipVO> relationships) {results.get(0).getData().get(0).getGraph().setRelationships(relationships);}
}
4.4.1.2GraphVO
@Data
public class GraphVO {private List<NodeVO> nodes = new ArrayList<>();private List<ShipVO> relationships = new ArrayList<>();
}
4.4.1.3NodeVO
@Data
@AllArgsConstructor
@NoArgsConstructor
public class NodeVO{private Long id;private List<String> labels;private Map<String, Object> properties;
}
4.4.1.4ShipVO
@Data
public class ShipVO {private Long id;private String type;private Long startNode;private Long endNode;private Map<String, Object> properties;
}
4.4.2 SDN查询解析
4.4.2.1 Repo查询语句
public interface D3jsRepo extends Neo4jRepository<Object, Long> {/*** @description:查询路径:根据roadName查询Road标签查询路径* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年8月21日 下午2:11:09*/@Query("MATCH (n:Road{name:$roadName}) MATCH path=(n)-[*]->(n1) RETURN path")List<Map<String, InternalPath.SelfContainedSegment[]>> findPathsByRoadName(@Param("roadName") String roadName);/*** @description:查询路径:根据标签label和某个属性字段查询路径,性能比较慢,谨慎使用* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年8月21日 下午3:22:02*/@Query("MATCH (n) WHERE $label IN labels(n) AND n[$property] = $value MATCH path=(n)-[*]->(n1) RETURN path")List<Map<String, InternalPath.SelfContainedSegment[]>> findByLabelAndProperty(@Param("label") String label, @Param("property") String property, @Param("value") String value);/*** @description:查询路径:根据标主键ID查询路径* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年8月21日 下午3:42:52*/@Query("MATCH (n) WHERE id(n) = $id MATCH path=(n)-[*]->(n1) RETURN path")List<Map<String, InternalPath.SelfContainedSegment[]>> findPathById(@Param("id") Long id);
}
4.4.2.2 解析Repo查询
@Service
public class D3jsServiceImpl implements D3jsService{@Autowiredprivate D3jsRepo d3jsRepo;/*** @description:通过节点ID找路径,以该节点为起点* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年8月22日 上午11:17:13*/@Overridepublic NeoResults findPathsById(Long id) {NeoResults neoResult = new NeoResults();List<NodeVO> nodes = new ArrayList<>();List<ShipVO> relationships = new ArrayList<>();List<Map<String, InternalPath.SelfContainedSegment[]>> paths = d3jsRepo.findPathById(id);for (Map<String, InternalPath.SelfContainedSegment[]> path : paths) {SelfContainedSegment[] segments = path.get("path");for (SelfContainedSegment segment : segments) {addNode(nodes, segment.start());addNode(nodes, segment.end());addShip(relationships, segment.relationship());}}neoResult.setNodes(nodes);neoResult.setRelationships(relationships);return neoResult;}/*** @description:添加关系* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年8月16日 下午1:23:54*/private void addShip(List<ShipVO> relationships, Relationship shipTemp) {ShipVO shipVO =new ShipVO();shipVO.setId(shipTemp.id());shipVO.setStartNode(shipTemp.startNodeId());shipVO.setEndNode(shipTemp.endNodeId());shipVO.setType(shipTemp.type());shipVO.setProperties(shipTemp.asMap());relationships.add(shipVO);}/*** @description:添加节点* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年8月16日 下午2:27:37*/private void addNode(List<NodeVO> nodes, Node nodeTemp) {NodeVO noveVO = new NodeVO();List<String> labels = new ArrayList<>();nodeTemp.labels().forEach(labels::add);noveVO.setId(nodeTemp.id());noveVO.setLabels(labels);noveVO.setProperties(nodeTemp.asMap());nodes.add(noveVO);}
}
4.4.2.3返回解析结果
@GetMapping("/node/info/path/{id}")@ApiOperationSupport(order = 3)@ApiOperation(value = "3获取指定节点为起点的路径")public NeoResults queryNodeTopo(@PathVariable Long id) {NeoResults findPaths = d3jsService.findPathsById(id);return findPaths;}
4.4.3前端处理渲染
<link rel="stylesheet" href="/plugin/neod3/css/neo4jd3.min.css">
<script src="/plugin/neod3/js/d3.min.js"></script>
<script src="/plugin/neod3/js/neo4jd3.js"></script>光路起点<select id = "selectRoad" class="selectpicker" onchange = "changeRoad()" data-live-search="true" data-style="btn-info" title="请选择起点光路" ></select><div id="neo4jd3"></div>
/*** @description:选择光路触发加载光路的路径* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年8月17日 下午2:10:18*/
function changeRoad(){let select = $('#selectRoad').val(); let url = '/node/info/path/'+select;let resultData = httpRequestForJson(url,"","GET");loadNeod3Topo(resultData);
}/*** @description:初始化节点拓扑矢量图* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年8月17日 下午2:18:48*/
var neo4jd3
function loadNeod3Topo(resultData){neo4jd3 = new Neo4jd3('#neo4jd3', {//showLabel源代码中不存在,是我自己添加的,实现效果为:节点是否显示节点标签showLabel: true,minCollision: 100,//neo4jDataUrl: '/aaa/bbbb',neo4jData: resultData,nodeRadius: 25,onNodeDoubleClick: function(node) {console.log('double click on node: ' + JSON.stringify(node));},onRelationshipDoubleClick: function(relationship) {console.log('double click on relationship: ' + JSON.stringify(relationship));},//自动缩放zoomFit: true,});
}
4.5实现效果

相关文章:
图数据库Neo4j学习五渲染图数据库neo4jd3
文章目录 1.现成的工具2.Neo4j JavaScript Driver3.neovis4.neo4jd34.1neo4jd3和neovis对比4.2获取neo4jd34.3neo4jd3的数据结构4.4Spring data neo4.4.1 定义返回数据格式4.4.1.1NeoResults4.4.1.2GraphVO4.4.1.3NodeVO4.4.1.4ShipVO 4.4.2 SDN查询解析4.4.2.1 Repo查询语句4.…...
AI增强的社交网络·导师·电话客服……
本月共更新80条知识, 智能时代,人与人之间的差距,体现在前沿知识的整合上。 # BeFake AI AI-augmented social network AI增强的社交网络,用户使用文本提示来生成图像,拍摄自己的“AI”版本。任何人都可以创建全新的虚…...
c# Task异步使用
描述 Task出现之前,微软的多线程处理方式有:Thread→ThreadPool→委托的异步调用,虽然可以满足基本业务场景,但它们在多个线程的等待处理方面、资源占用方面、延续和阻塞方面都显得比较笨拙,在面对复杂的业务场景下&am…...
QuickLook概述和使用以及常用插件
1、QuickLook概述 QuickLook: 是可以快速预览的工具,开源、免费。通过空格键即可快速查看文件内容。 文件无需打开就可以用QuickLook一键快速预览。 说明文档:https://en.wikipedia.org/wiki/Quick_Look github地址:https://git…...
1A快恢复整流二极管型号汇总
快恢复整流二极管是二极管中的一种,开关特性好、反向恢复时间短,在开关电源、PWM脉宽调制器、变频器等电子电路中经常能看到它的身影。快恢复整流二极管的内部结构与普通PN结二极管不同,它属于PIN结型二极管,即在P型硅材料与N型硅…...
【element-ui】el-dialog改变宽度
dialog默认宽度为父元素的50%,这就导致在移动端会非常的窄,如图1,需要限定宽度。 解决方法:添加custom-class属性,然后在style中编写样式,注意,如果有scoped限定,需要加::v-deep &l…...
第三讲,实践编程 Eigen
目录 1.实践 Eigen1.1 Eigen的简介1.2 Eigen 向量和矩阵的 声明1.3 Eigen的输出操作1.4 矩阵和向量相乘 要注意数据类型 矩阵纬度1.5 矩阵的四则运算1.6 矩阵求解特征向量和特征值1.7 解方程 求逆 1.实践 Eigen 1.1 Eigen的简介 Eigen是一个 C 开源线性代数库。它提供了快…...
POI实现百万数据导出
1、概述 我们都知道Excel可以分为早期的Excel2003版本(使用POI的HSSF对象操作)和Excel2007版本(使用POI的XSSF操作),两者对百万数据的支持如下: Excel 2003:在POI中使用HSSF对象时&#…...
如何制作党建专题汇报片
通过展示党组织的凝聚力和战斗力,增强党员的组织归属感和团结合作意识。通过宣传片,可以加强党组织的凝聚力,推动党的事业发展。制作党建专题汇报片需要一定的前期准备和后期制作技巧。下面是由深圳党建专题汇报片制作公司老友记小编为您整理…...
沉浸式VR虚拟实景样板间降低了看房购房的难度
720 全景是一种以全景视角为特点的虚拟现实展示方式,它通过全景图像和虚拟现实技术,将用户带入一个仿佛置身其中的沉浸式体验中。720 全景可以应用于旅游、房地产、展览等多个领域,为用户提供更为直观、真实的体验。 在房地产领域,…...
如何在Linux环境下给Web应用配置HTTPS证书
如何在Linux环境下给Web应用配置HTTPS证书 在当今互联网时代,保护用户数据的安全性至关重要。为你的Web应用启用HTTPS协议是确保数据传输加密和身份验证的一种有效方式。本文将指导你如何在Linux环境下为Web应用程序配置HTTPS证书。 1. 获取SSL证书 首先…...
面试题-React(七):React组件通信
在React开发中,组件通信是一个核心概念,它使得不同组件能够协同工作,实现更复杂的交互和数据传递。常见的组件通信方式:父传子和子传父 一、父传子通信方式 父组件向子组件传递数据是React中最常见的一种通信方式。这种方式适用…...
MASM32编程调用 API函数RtlIpv6AddressToString,Windows 10 容易,Windows 7 折腾
一、需求分析 最近用MASM32编程更新SysInfo,增加对IPv6连接信息的收集功能,其中涉及到 MIB_TCP6ROW_OWNER_MODULE 结构体: ;typedef struct _MIB_TCP6ROW_OWNER_MODULE { ; UCHAR ucLocalAddr[16]; ; DWORD dwLocalScope…...
为什么使用Nacos而不是Eureka(Nacos和Eureka的区别)
文章目录 前言一、Eureka是什么?二、Nacos是什么?三、Nacos和Eureka的区别3.1 支持的CAP3.2连接方式3.3 服务异常剔除3.4 操作实例方式 总结 前言 为什么如今微服务注册中心用Nacos相对比用Eureka的多了?本文章将介绍他们之间的区别和优缺点…...
Python作业一
目录 1、用循环语句求122333444455555的和 2、求出2000-2100的所有闰年,条件是四年一闰,百年不闰,四百年再闰 3、输入两个正整数,并求出它们的最大公约数和最小公倍数 4、求出100以内的所有质数 5、求100以内最大的10个质数的…...
protobuf概览
protobuf protobuf是由谷歌推出的二进制序列化与反序列化库对象。也是著名GRPC的底层依赖,它独立于平台及语言的序列化与反序列化标准库。 相关网址 protobuf IDL描述protobuf 开源库grpc-知乎grpc官方示例 安装protobuf可以使用vcpkg进行简易安装依赖ÿ…...
<C++> SSE指令集
SSE指令集 include库 #include <mmintrin.h> //MMX #include <xmmintrin.h> //SSE(include mmintrin.h) #include <emmintrin.h> //SSE2(include xmmintrin.h) #include <pmmintrin.h> //SSE3(include emmintrin.h) #include <tmmintrin.h> /…...
cortex-A7核LED灯实验--STM32MP157
实验目的:实现LED1 / LED2 / LED3三盏灯工作 一,分析电路图 1,思路 分析电路图可知: 网络编号 引脚编号 LED1 PE10 LED2 > PF10 LED3 > PE8 2,工作原理: 写1:LED灯亮…...
WPF实战项目十三(API篇):备忘录功能api接口、优化待办事项api接口
1、新建MenoDto.cs /// <summary>/// 备忘录传输实体/// </summary>public class MenoDto : BaseDto{private string title;/// <summary>/// 标题/// </summary>public string Title{get { return title; }set { title value; }}private string con…...
clickhouse(十四、分布式DDL阻塞及同步阻塞问题)
文章目录 一、分布式ddl 阻塞、超时现象验证方法解决方案 二、副本同步阻塞现象验证解决方案 一、分布式ddl 阻塞、超时 现象 在clickhouse 集群的操作中,如果同时执行一些重量级变更语句,往往会引起阻塞。 一般是由于节点堆积过多耗时的ddl。然后抛出…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
