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

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

最近做毕设,后端采用的是 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
    18 引用 • 18 回帖
  • Vue.js

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

    261 引用 • 662 回帖 • 1 关注
  • 异步
    10 引用 • 51 回帖

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 543 关注
  • Mobi.css

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

    1 引用 • 6 回帖 • 698 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    169 引用 • 799 回帖
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖 • 1 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 16 关注
  • OnlyOffice
    4 引用 • 19 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 429 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    108 引用 • 54 回帖 • 1 关注
  • Windows

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

    215 引用 • 462 回帖 • 2 关注
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 7 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖 • 3 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 1 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    129 引用 • 793 回帖 • 2 关注
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    198 引用 • 120 回帖
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 87 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    27 引用 • 66 回帖 • 1 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1425 引用 • 10043 回帖 • 469 关注
  • InfluxDB

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

    2 引用 • 53 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    85 引用 • 1201 回帖 • 449 关注
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 245 关注
  • 996
    13 引用 • 200 回帖 • 4 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 133 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 2 关注
  • 安全

    安全永远都不是一个小问题。

    189 引用 • 813 回帖 • 1 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 3 关注