前言
发现一个很有用的vue插件:https://www.npmjs.com/package/vue-neo4j
这个能在前端直连neo4j服务器啦,下图就是测试效果绘制三国人物图谱关系
版本说明
- vue
3.0版本
- vue-neo4j
0.4.8版本
- neo4j服务端版本
4.3.6版本
,可以直接去官网下载。 - echarts
5.22版本
开发说明
一、windows服务器部署neo4j
1、部署jdk11, 因为neo4j 4.3.6使用的版本是jdk11以上,否则启动不了哦
2、下载neo4j,解压
3、到 .\conf目录修改 neo4j.conf文件修改default_listen_address为0.0.0.0,因为不改的话,会导致启动后只能本机访问
4、cmd到.\bin目录执行 noe4j console. 这样就完成启动了
5、浏览器打开网址 http://127.0.0.1:7474
默认密码为neo4j/neo4j 首次进入会提示修改密码
二、vue3.0 版本前端工程说明
1、引入依赖 yarn add vue-neo4j
2、由于vue-neo4j 0.4.8 该版本只适配vue2.0版本,所以要改下源码,把 vue.property.$neo4j
改为 vue.config.globalproperties.$neo4j
3、main.js引入
import vueneo4j from 'vue-neo4j'; let app = createapp(app); app.use(vueneo4j );
4、逻辑编写
<template> <div class="neo4jmain"> <div class="addcontent"> <el-form :inline="true" :model="forminline" :rules="rules" ref="neo4jform"> <el-form-item label="开始节点名称" prop="startnode"> <el-input v-model="forminline.startnode" placeholder="请输入开始节点名称"></el-input> </el-form-item> <el-form-item label="关系名称" prop="relationname"> <el-input v-model="forminline.relationname" placeholder="请输入关系名称"></el-input> </el-form-item> <el-form-item label="结束节点名称" prop="endnode"> <el-input v-model="forminline.endnode" placeholder="请输入结束节点名称"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onsubmit">提交</el-button> <!-- <el-button type="primary" @click="ondelete">清空表</el-button>--> </el-form-item> </el-form> </div> <div class="echarts" ref="echarts"> </div> </div> </template> <script> import * as echarts from 'echarts' export default { name: "main.vue", mounted() { this.query(); }, data() { return { forminline: { startnode: '', endnode: '', relationname: '' }, rules: { startnode: [{required: true, trigger: 'blur'}], endnode: [{required: true, trigger: 'blur'}], relationname: [{required: true, trigger: 'blur'}] }, protocol: 'bolt', host: '127.0.0.1', port: 7687, username: 'neo4j', password: '123456', echartsdata: [], nodesrelation: [] } }, methods: { ondelete() { this.connect(); const session = this.$neo4j.getsession(); let cypher = `match p=(n:person)-[]->(m:person) delete p `; session.run(cypher); cypher = `match (n:person) delete n`; session.run(cypher).then(() => { session.close() }); this.query(); }, initecharts() { // 基于准备好的dom,初始化echarts实例 let mychart = echarts.init(this.$refs.echarts) // 绘制图表 mychart.setoption({ title: { text: 'neo4j 图谱关系' }, tooltip: {}, animationdurationupdate: 1500, animationeasingupdate: 'quinticinout', series: [ { type: 'graph', layout: 'force', force: { edgelength: 40, repulsion: 50, gravity: 0.1 }, symbolsize: 50, roam: true, label: { show: true }, edgesymbol: ['circle', 'arrow'], edgesymbolsize: [4, 10], edgelabel: { fontsize: 20 }, data: this.echartsdata, // links: [], links: this.nodesrelation, linestyle: { opacity: 0.9, width: 2, curveness: 0 } } ] }); }, query() { this.connect(); const session = this.$neo4j.getsession(); let cypher = `match p=(n:person)-[]->(m:person) return p limit 1000`; session.run(cypher).then(res => { let records = res.records; let nodes = new set(); this.nodesrelation = []; for (let i = 0; i < records.length; i++) { nodes.add(records[i]._fields[0].segments[0].start.properties.name); nodes.add(records[i]._fields[0].segments[0].end.properties.name); this.nodesrelation.push({ source: records[i]._fields[0].segments[0].start.properties.name, target: records[i]._fields[0].segments[0].end.properties.name, linestyle: { curveness: 0 }, label: { show: true, formatter: function() { return records[i]._fields[0].segments[0].relationship.type } } }); } let curveness = [0, 0.4, -0.4, 0.3, -0.3, 0.2, -0.2, 0.1, -0.1]; for (let j = 0; j < this.nodesrelation.length; j++) { let repeatnumber = 0; for (let s = j+1; s < this.nodesrelation.length; s++) { let r1 = this.nodesrelation[j]; let r2 = this.nodesrelation[s]; if (r1.source === r2.source && r1.target === r2.target) { repeatnumber = repeatnumber + 1; } else if (r1.target === r2.source && r1.source === r2.target) { repeatnumber = repeatnumber + 1; } } this.nodesrelation[j].repeatnumber = repeatnumber; } for (let j = 0; j < this.nodesrelation.length; j++) { console.log(this.nodesrelation[j].repeatnumber); this.nodesrelation[j].linestyle.curveness = curveness[this.nodesrelation[j].repeatnumber]; } this.echartsdata = []; nodes.foreach((e) => { let index = math.ceil(math.random()*10); let color = () => { if (index%4===0) { return '#228b22' } else if (index%4===1) { return '#ffff00' } else if (index%4===2) { return '#20b2aa' } else if (index%4===3) { return '#ffb6c1' } return '#87cefa'; } this.echartsdata.push({ name: e, x: math.random() * 100, y: math.random() * 100, itemstyle: { color: color() } }); }) this.initecharts(); }).then(() => { session.close() }); }, onsubmit() { this.$refs.neo4jform.validate((valid) => { if (valid) { this.connect(); const session = this.$neo4j.getsession(); let cypher = `merge (n:person{name: '${this.forminline.startnode}'}) merge (m:person{name: '${this.forminline.endnode}'}) merge (n)-[r:${this.forminline.relationname}]->(m)`; session.run(cypher).then(() => { this.forminline = { startnode: '', endnode: '', relationname: '' }; this.query(); }).then(() => { session.close() }); } }) }, connect() { return this.$neo4j.connect(this.protocol, this.host, this.port, this.username, this.password); }, driver() { // get a driver instance return this.$neo4j.getdriver() }, testquery() { // get a session from the driver const session = this.$neo4j.getsession() // or you can just call this.$neo4j.run(cypher, params) session.run('match (n) return n') .then(res => { console.log(res) // console.log(res.records[0].get('count')) }) .then(() => { session.close() }) } } } </script> <style scoped lang="less"> .neo4jmain { height: 100%; display: flex; flex-direction: column; .addcontent { padding: 15px; box-shadow: -10px 0 10px #d3d3d3, /*左边阴影*/ 10px 0 10px #d3d3d3, /*右边阴影*/ 0 -10px 10px #d3d3d3, /*顶部阴影*/ 0 10px 10px #d3d3d3; } .echarts { background-color: #333; flex: 1; flex-grow: 1; } } </style>
心得:
- 优点是前端可以直接操作数据库,弊端是数据库配置暴露了。
- 建议还是通过后端连接数据库操作数据。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论