使用 Vue+axios+Echarts 绘制关系图遇到的坑

本贴最后更新于 1921 天前,其中的信息可能已经时过境迁

最近做毕设,后端采用的是 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>

  • axios
    7 引用 • 5 回帖
  • ECharts
    20 引用 • 20 回帖 • 1 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    268 引用 • 666 回帖 • 1 关注
  • 异步
    10 引用 • 51 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 180 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 143 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 266 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 88 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    43 引用 • 44 回帖
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 766 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖 • 2 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖 • 2 关注
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    229 引用 • 476 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 9 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖 • 2 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 367 关注
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    315 引用 • 547 回帖
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 672 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 733 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖 • 1 关注
  • Word
    13 引用 • 41 回帖 • 1 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    125 引用 • 74 回帖 • 2 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    84 引用 • 414 回帖
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 87 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 105 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 2 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    53 引用 • 190 回帖