最近做毕设,后端采用的是Spring boot,通过Neo4jRepository从neo4j中获取数据,前端框架是Vue,通过axios请求后端数据,并处理成符合Echarts规范的数据格式,之后Echarts进行渲染。在前端渲染数据的过程中遇到好多坑。
首先是如何对后端返回的数据进行处理。后端返回的数据格式是这样的:
[
{
"id": 1,
"name": "CSS"
},
{
"id": 2,
"name": "Javascript",
"derives": [
{
"id": 3,
"name": "Vue.js"
}
]
},
{
"id": 3,
"name": "Vue.js"
},
{
"id": 171,
"name": "前端技术",
"includes": [
{
"id": 1,
"name": "CSS"
},
{
"id": 2,
"name": "Javascript",
"derives": [
{
"id": 3,
"name": "Vue.js"
}
]
},
{
"id": 172,
"name": "HTML",
}
]
},
{
"id": 172,
"name": "HTML",
}
]
对应的Echarts规范数据应当是:
data:[
{
name: "CSS"
},
{
name: "Javascript"
},
{
name: "Vue.js"
},
{
name: "前端技术"
},
{
name: "HTML"
}
],
links: [
{
source: "Javascript",
target: "Vue.js",
name: "衍生出"
},
{
source: "前端技术",
target: "HTML",
name: "包含"
},
{
source: "前端技术",
target: "CSS",
name: "包含"
},
{
source: "前端技术",
target: "Javascript",
name: "包含"
}
]
遇到的坑主要是两个。第一个是处理返回的数据,返回数据存在对象resData中,我建立了两个空白数组graphData和graphLinkes用于存储包装好的数据,然后使用for循环处理resData,正确的代码如下:
for(var i=0,len=response.data.length;i<len;i++){
me.graphData.push({
name: me.resData[i].name,
des: 'nodedes05',
symbolSize: 50,
category: 1,
});
if("includes" in me.resData[i]){
let dataIncludes=me.resData[i].includes;
for(var j=0,lenj=dataIncludes.length;j<lenj;j++){
me.graphLinks.push({
source: me.resData[i].name,
target: dataIncludes[j].name,
name: '包含',
des: j
})
}
}
if("derives" in me.resData[i]){
let dataDerives=me.resData[i].derives;
for(var j=0,lenj=dataDerives.length;j<lenj;j++){
me.graphLinks.push({
source: me.resData[i].name,
target: dataDerives[j].name,
name: '衍生出',
des: j
})
}
}
}
但是一开始我想用for in循环却一直失败,不知道怎么回事。最后只能用最传统的i++。
第二个坑在Echarts渲染上。从后台获取数据的和渲染图形分别写在两个方法中,方法名为loadData和drawline。一开始我是在mounted中先执行loadData,再执行drawline。但这样不能用。后来去网上搜了一下说是在获取到数据后立马执行drawline才行,不过网上也没有说为什么。我想了一下这应该是异步执行的问题。如果因为在loadData中使用的axios是异步方法,也就是不需要完全执行完里面的语句就可以继续执行后面的方法。因此在我们调用drawline的时候数据根本还没有从后台接口获取到。而如果在获取数据后立马执行,更确切的说是在axios then方法体内立马执行,而在axios方法内部的语句还是同步执行的,这就保证了我们已经从后台接口获取到了数据,之后渲染就没问题了。
完整代码如下:
<template>
<div id="myChart"></div>
</template>
<style>
#myChart{
width: 100%;
height: 1000px;
}
</style>
<script>
export default {
name:"Graph",
data () {
return {
msg: 'Welcome to Your Vue.js App',
categories: [],
resData: [],
graphData: [],
graphLinks: []
}
},
mounted(){
for (var i = 0; i < 2; i++) {
this.categories[i] = {
name: '类目' + i
};
}
this.loadData();
//this.drawLine();
},
methods: {
drawLine(){
// 基于准备好的dom,初始化echarts实例
let myChart = this.$echarts.init(document.getElementById('myChart'));
// 绘制图表
myChart.setOption({
title: {
text: 'ECharts 关系图'
},
tooltip: {},
series: [{
type: 'graph', // 类型:关系图
layout: 'force', //图的布局,类型为力导图
symbolSize: 40, // 调整节点的大小
roam: true, // 是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启
edgeSymbol: ['circle', 'arrow'],
edgeSymbolSize: [2, 10],
edgeLabel: {
normal: {
textStyle: {
fontSize: 20
}
}
},
force: {
repulsion: 2500,
edgeLength: [10, 50]
},
draggable: true,
lineStyle: {
normal: {
width: 2,
color: '#4b565b',
}
},
edgeLabel: {
normal: {
show: true,
formatter: function (x) {
return x.data.name;
}
}
},
label: {
normal: {
show: true,
textStyle: {}
}
},
data: this.graphData,
links: this.graphLinks,
categories: this.categories,
}]
});
},
loadData(){
let me=this;
axios.get('http://localhost:8080/graph/all')
.then(function (response){
me.resData=response.data;
for(var i=0,len=response.data.length;i<len;i++){
me.graphData.push({
name: me.resData[i].name,
des: 'nodedes05',
symbolSize: 50,
category: 1,
});
if("includes" in me.resData[i]){
let dataIncludes=me.resData[i].includes;
for(var j=0,lenj=dataIncludes.length;j<lenj;j++){
me.graphLinks.push({
source: me.resData[i].name,
target: dataIncludes[j].name,
name: '包含',
des: j
})
}
}
if("derives" in me.resData[i]){
let dataDerives=me.resData[i].derives;
for(var j=0,lenj=dataDerives.length;j<lenj;j++){
me.graphLinks.push({
source: me.resData[i].name,
target: dataDerives[j].name,
name: '衍生出',
des: j
})
}
}
}
me.drawLine();
})
.catch(function (error) {
console.log(error);
});
}
}
}
</script>
标题:使用 Vue+axios+Echarts 绘制关系图遇到的坑
作者:aopstudio
地址:https://neusoftware.top/articles/2022/02/19/1586781400472.html