This is a creation in Article, where the information may have evolved or changed.
Brief introduction
Preview
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 Impl Ements access to tar archives. "," Target ":"/usr/local/go/pkg/darwin_amd64/archive/tar.a "," Goroot ": true," stand ARD ": 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", "strc Onv.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", "Mat H "," OS ","Path", "Path/filepath", "reflect", "runtime", "Runtime/internal/atomic", "Runtime/inte Rnal/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", "Cryp To/md5 "," FMT "," internal/testenv "," io "," Io/ioutil "," math "," OS "," Pat H "," 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.
/* Convert raw Data to icon-friendly data. Importpath as a unique ID and label; Imports are used to calculate dependencies; The size of the node depends on the number of times it is dependent; */function Transdata (datas) {/* stores dependent path information. */Let edges = []/* Stores the underlying node information. */Let nodes = []/* node size. The initial is 1, each Introduced once plus 1. */Let nodedsize = {}/* Dimension Unit 1. */Let UnitSize = 1.5 datas.map (data) =>{let ItemId = data. Importpath Nodes.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})}})/* The dimension data is merged onto the node. */Nodes.map (item) =>{Let ItemId = Item.id if (Nodedsize[itemid]) {item.size = Nodedsize[it EmId]}}) 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