使用echarts画设备拓扑图

举报
拿我格子衫来 发表于 2022/03/17 22:32:08 2022/03/17
【摘要】 开发需求背景 今天领导派了一个小活,要求我将公司的物联网平台的网络拓扑图画出来。做一个数据展示的页面,集成到现有的iot平台上。 说到拓扑图,大家都也都比较清楚,能够清晰地表示网络链路的链接关系。 ...

开发需求背景

今天领导派了一个小活,要求我将公司的物联网平台的网络拓扑图画出来。做一个数据展示的页面,集成到现有的iot平台上。

说到拓扑图,大家都也都比较清楚,能够清晰地表示网络链路的链接关系。

官方一点的解释是:
网络拓扑结构是指用传输媒体互连各种设备的物理布局(将参与LAN工作的各种设备用媒体互连在一起有多种方法,但是实际上只有几种方式能适合LAN的工作)。
网络拓扑图是指由网络节点设备和通信介质构成的网络结构图。

一般的拓扑图都是这样子的

还有这一种

这些设计图都是架构师使用软件画出来的,数据都是固定的,不支持动态修改,没有动效,而我们需要支持动态添加网络节点。需要有动效。

经过一天不歇的努力,终于在下班前做出来了一个原型图。

先给大家看看,下面来详细讲解如何使用echarts一步一步完成这个拓扑图的。

技术调研

接到需求后我调研了几个物联网仪表盘后,我觉得使用echart来试试,因为d3太难了。😃

拓扑图中需要与几个实体,代表链路中的每一个设备,一个设备可能有进线,有出线,也有可能有多条线,线的条数都不能固定的。因为随着设备的增加,中央机器到达各个设备的线也是逐渐增加的。设备之间有线,有了线,就要有流量的流动,就是在线上方覆盖一个箭头,逐渐从数据的发出方到达数据的接受方。此外每台设备都要有个名称,鼠标放到设备上,需要有一个动效,最好能显示一些详细情况。

ok
需求分析完毕,一个图大致有以下几个视图

  • 设备
  • 设备之间的线
  • 线上的流量流向箭头
  • 设备的附加信息
  • 其他动效

开始编码

在真正的编码开始之前,我们需要对这个需求有个抽象的概念,怎么抽象那?
我们可以将设备,线,箭头,都看做物品,而这些物品都存在于一个平面直角坐标系上。有了平面直角坐标系也就有了他们各自的位置。
比如设备1的坐标是x: 500 y: 1000, 设备2的坐标是 x: 500 y: 600

那么设备2就是在设备1的下方。 而设备1到设备2的链接,也就是好说了, 这条线段的的气质坐标是{x: 500 y: 1000} => {x: 500, y: 600}
这样就非常容易理解了。而echarts是支持 使用二维的直角坐标系(也称笛卡尔坐标系)。
具体设置是在series 中的一些类型下, 设置coordinateSystemcartesian2d

官方文档的解释。

思路清晰了,我们先来做一个简单的。
先画出二个设备,然后再连线。

定义二个设备

{
  x: 500,
  y: 1000,
  nodeName: '服务器',
  svgPath: 'M544 552.325V800a32 32 0 0 1-32 32 31.375 31.375 0 0 1-32-32V552.325L256 423.037a32 32 0 0 1-11.525-43.512A31.363 31.363 0 0 1 288 368l224 128 222.075-128a31.363 31.363 0 0 1 43.525 11.525 31.988 31.988 0 0 1-11.525 43.513L544 551.038z m0 0,M64 256v512l448 256 448-256V256L512 0z m832 480L512 960 128 736V288L512 64l384 224z m0 0',
  symbolSize: 70,
},
{
  x: 500,
  y: 600,
  nodeName: '设备1',
  svgPath: 'M1172.985723 682.049233l-97.748643-35.516964a32.583215 32.583215 0 0 0-21.830134 61.582735l25.7398 9.123221-488.744218 238.181638L115.670112 741.349163l47.245961-19.223356a32.583215 32.583215 0 0 0-22.808051-60.604819l-119.579777 47.896905a32.583215 32.583215 0 0 0 0 59.952875l557.820313 251.540496a32.583215 32.583215 0 0 0 27.695632 0l570.527227-278.584184a32.583215 32.583215 0 0 0-3.258721-59.952875z,M1185.041693 482.966252l-191.587622-68.749123a32.583215 32.583215 0 1 0-21.831133 61.254764l118.927833 43.010323-488.744218 237.855666-471.474695-213.744727 116.973-47.244961a32.583215 32.583215 0 1 0-24.111938-60.604819l-190.609705 75.593537a32.583215 32.583215 0 0 0-20.528246 29.650465 32.583215 32.583215 0 0 0 20.528246 30.30141l557.819313 251.866468a32.583215 32.583215 0 0 0 27.695632 0l570.201254-278.584184a32.583215 32.583215 0 0 0 18.24744-30.953354 32.583215 32.583215 0 0 0-21.505161-29.651465z,M32.583215 290.075742l557.819313 251.540496a32.583215 32.583215 0 0 0 27.695632 0l570.201254-278.584184a32.583215 32.583215 0 0 0-3.257721-59.952875L626.244463 2.042365a32.583215 32.583215 0 0 0-23.134022 0l-570.527226 228.080502a32.583215 32.583215 0 0 0-19.224357 30.627382 32.583215 32.583215 0 0 0 19.224357 29.325493zM615.817355 67.534767l474.733416 170.408432-488.744218 238.180638-471.474695-215.372588z'
},

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

x, y 代表设备的坐标, nodeName定义了设备的名称, svgPath是使用svg的指令语法来生成一个设备图标。
效果图

定义连线

{
            coords:
            [
                [500, 1000],
                [500, 800],
            ]
        },
		{
            coords: [
                [500, 800],
                [500, 600],

            ]
        },

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

效果图

解释:
coords作为一个数组,存放的是几个点的坐标

[
   [500, 1000],
   [500, 800],
]

  
 
  • 1
  • 2
  • 3
  • 4

数组的第一个元素表示起点,第二个元素表示终点
那么这条线段就是从 x500,y1000 到达 x500,y800

完整的代码

var nodes = [{
        x: 500,
        y: 1000,
        nodeName: '应用',
        svgPath: 'M544  ',
        symbolSize: 70,

    }, {
        x: 100,
        y: 600,
        nodeName: '模块1',
        svgPath: 'M1172.  '
    },
    {
        x: 500,
        y: 600,
        nodeName: '模块2',
        svgPath: 'M1 615.817355 67.534767l474.733416 170.408432-488.744218 238.180638-471.474695-215.372588z'
    },
    {
        x: 900,
        y: 600,
        nodeName: '模块3',
        svgPath: 'M117 615.817355 67.534767l474.733416 170.408432-488.744218 238.180638-471.474695-215.372588z'
    },
    {
        x: 0,
        y: 300,
        nodeName: '节点1',
        svgPath: 'M887.5  68 68.25472-68.224 68.28544l-0.06144-0.06656z',
    },
    {
        x: 300,
        y: 300,
        nodeName: '节点2',
        svgPath: 'M88  37.71392 0 68.29056 30.57152 68.28544 68.29056 0 37.68832-30.53568 68.25472-68.224 68.28544l-0.06144-0.06656z',
    },
    {
        x: 700,
        y: 300,
        nodeName: '节点3',
        svgPath: 'M887.55  25472-68.224 68.28544l-0.06144-0.06656z',
    },
    {
        x: 1000,
        y: 300,
        nodeName: '节点4',
        svgPath: 'M887.55 0.53568 68.25472-68.224 68.28544l-0.06144-0.06656z',
    },
]
var charts = {
    nodes: [],
    linesData: [{
            coords: [
                [500, 1000],
                [500, 800],
            ]
        }, {
            coords: [
                [500, 800],
                [100, 800],
                [100, 600]

            ]
        }, {
            coords: [
                [500, 800],
                [500, 600],

            ]
        }, {
            coords: [
                [500, 800],
                [900, 800],
                [900, 600]

            ]
        },
        {
            coords: [
                [100, 600],
                [0, 300]
            ]
        },
        {
            coords: [
                [100, 600],
                [300, 300]
            ]
        },
        {
            coords: [
                [900, 600],
                [700, 300]
            ]
        },
        {
            coords: [
                [900, 600],
                [1000, 300]
            ]
        }
    ]
}
for (var j = 0; j < nodes.length; j++) {
    const {
        x,
        y,
        nodeName,
        svgPath,
        symbolSize
    } = nodes[j];
    var node = {
        nodeName,
        value: [x, y],
        symbolSize: symbolSize || 50,
        symbol: 'path://' + svgPath,
        itemStyle: {
            color: 'orange',
        }
    }
    charts.nodes.push(node)
}

option = {
    backgroundColor: "#0B1321",
    xAxis: {
        min: 0,
        max: 1000,
        show: false,
        type: 'value'
    },
    yAxis: {
        min: 0,
        max: 1000,
        show: false,
        type: 'value'
    },
    series: [{
        type: 'graph',
        coordinateSystem: 'cartesian2d',
        label: {
            show: true,
            position: 'bottom',
            color: 'orange',
            formatter: function(item) {
                return item.data.nodeName
            }
        },
        data: charts.nodes,
    }, {
        type: 'lines',
        polyline: true,
        coordinateSystem: 'cartesian2d',
        lineStyle: {
            type: 'dashed',
            width: 2,
            color: '#175064',
            curveness: 0.3

        },
        effect: {
            show: true,
            trailLength: 0.1,
            symbol: 'arrow',
            color: 'orange',
            symbolSize: 8
        },
        data: charts.linesData
    }]
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171

这里svg的指令太多,我删减了一部分,具体的动效图。

技术回顾

使用echart画物联网各种仪表盘时,掌握坐标系就掌握了各个物体的位置。随你发挥.
此外需要注意一下,我们的设备图表使用的是series-graph 可以用于展现节点以及节点之间的关系数据。

写在最后

掌握住echarts的配置项,可以画出很多精美的仪表盘,后续我和大家继续分享其他的物联网相关的仪表盘.如果文章对你有帮助,请记得点赞留言。

文章来源: fizzz.blog.csdn.net,作者:拿我格子衫来,版权归原作者所有,如需转载,请联系作者。

原文链接:fizzz.blog.csdn.net/article/details/115246658

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。