前言
发现一个很有用的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>
心得:
- 优点是前端可以直接操作数据库,弊端是数据库配置暴露了。
- 建议还是通过后端连接数据库操作数据。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论