This is a creation in Article, where the information may have evolved or changed.
Brief introduction
National Day reading << Go language Bible >> always want to do something to deepen the impression. Visualizing the dependencies between the Golang standard libraries can be a good entry point. Before doing, a simple search of the relevant content, online also to discuss, But there's no way to find out. The standard library is bound to have dependencies, and the degree of dependence of different libraries is necessarily not the same. But how much difference does it make?
The data is derived from the standard library of the Golang 1.9 version of the real world. Therefore, this article is not only a visual related discussion article, but also provides a quick carding tool that can directly explore the dependencies between Golang standard libraries.
Data preparation
The correlation between the packages of the standard library can be obtained directly from the command and then simply transformed into a standard JSON object:
go list -json std
Example output:
{"Dir": "/usr/local/go/src/archive/tar", "Importpath": "Archive/tar", "Name": "Tar", "DOC": "Package tar implements Access to tar archives. "," Target ":"/usr/local/go/pkg/darwin_amd64/archive/tar.a "," Goroot ": True," standard ": true," Stalereason ":" Standard package in Go release distribution "," Root ":"/usr/local/go "," Gofiles ": [" Common.go "," Format.go "," Reader.go "," Stat_atimespec.go "," Stat_unix.go "," Strconv.go "," Writer.go "]," ignoredgofiles ": [" Stat_atim.go "]," Imports ": [" bytes "," Errors "," FMT "," io "," Io/ioutil "," math "," OS "," path "," Sort "," StrConv "," strings "," Syscall "," Time "]," Deps ": [" bytes "," Errors "," FMT "," Internal/cpu "," Internal/poll "," Internal/race "," io "," Io/ioutil "," math "," Os "," Path "," Path/filepath "," reflect "," runtime "," Runtime/internal/atomic "," Runtime/internal/sys "," Sort "," StrConv "," Strings "," Sync "," sync/atomic "," Syscall "," Time "," Unicode "," Unicode/utf8 "," unsafe "]," testgofiles ": [" Reader_test.go "," Strconv_test.go "," Tar_test.go "," Writer_test.go "]," testimports ": [" bytes "," Crypto/md5 "," FMT "," INternal/testenv "," io "," Io/ioutil "," math "," OS "," Path "," Path/filepath "," reflect "," sort "," strings "," testing "," Testing/iotest "," Time "]," xtestgofiles ": [" Example_test.go "]," xtestimports ": [" Archive/tar "," bytes "," FMT "," IO "," Log "," OS "]}
Comb the data source, see: Https://raw.githubusercontent.com/ios122/graph-go/master/data.js
The principle of visualization
Mainly involved in the content:
Visual display, using the Echarts
Use the Importpath of the original data instead of Name as the unique ID for each data node. This is because the Golang itself is determined by the package naming specification.
Use the original data's Imports field to determine the interdependencies between the standard library package and the package. Golang is not allowed to be circular dependent, so some loops rely on related issues that do not need to be considered.
The size of the node is positively correlated with the number of times the packet was introduced into the other package. In doing so, the more packets that are dependent on the package, the larger the image will be when it is finally displayed. Common and less frequently used packages, at a glance.
Data collation
Is the raw data, processing into the echarts needs of the data, here briefly say the core of the idea:
Echarts displays the relevant code, largely referencing the GRAPH-NPM
node coordinates and colors, using random coordinates and colors, to remove the connection between the node and the packet. I think this is a more pure way to see the connection between the standard library package and the package.
A edges is required to record the dependencies between packages and packages. Dynamically writes every time you traverse an Imports .
A nodes is required to record some information about the package itself, but its size parameter requires that all dependencies be calculated and then filled in.
Using Nodedsize to record the number of times each packet is dependent, it is a dictionary map in order to improve efficiency.
/* 将原始数据,转换为图标友好的数据. ImportPath 作为唯一 id 和 标签;Imports 用于计算依赖关系;节点的大小,取决于被依赖的次数;*/function transData(datas){/* 存储依赖路径信息. */let edges = []/* 存储基础节点信息. */let nodes = []/* 节点尺寸.初始是1, 每被引入一次再加1. */let nodedSize = {}/* 尺寸单位1. */let unitSize = 1.5datas.map((data)=>{let itemId = data.ImportPathnodes.push({"label": itemId,"attributes": {},"id": itemId,"size": 1})if(data.Imports){data.Imports.map((importItem)=>{edges.push({"sourceID": importItem,"attributes": {},"targetID": itemId,"size": unitSize})if(nodedSize[importItem]){nodedSize[importItem] = nodedSize[importItem] + unitSize}else{nodedSize[importItem] = unitSize}})}})/* 尺寸数据合并到节点上. */nodes.map((item)=>{let itemId = item.idif(nodedSize[itemId]){item.size = nodedSize[itemId]}})return {nodes,edges}}
Effect and source code
- GitHub Source: Https://github.com/ios122/graph-go
- Echarts Online preview: Http://gallery.echartsjs.com/editor.html?c=xSyJNqh8nW
RELATED LINKS