简介

国庆看完 << Go 语言圣经 >>,总想做点什么,来加深下印象.以可视化的方式展示 golang 标准库之间的依赖,可能是一个比较好的切入点.做之前,简单搜了下相关的内容,网上也要讨论,但是没有发现直接能拿过来用的.标准库之间,是必然存在依赖关系的,不同库被依赖的程度必然是不一样的.但究竟有多大差别呢?

以下内容,数据源自真实环境的 golang 1.9 版本的标准库.所以,本文不仅是一篇可视化相关的讨论文章,更是提供了一个可以直接探究 golang 标准库间依赖关系的快速梳理工具.

数据准备

标准库各个包之间的相互关系,可以直接通过命令获取,然后简单变换为一个标准的 JSON 对象:

go list -json  std

示例输出:

{
"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"
]
}

梳理过的数据源,参见: https://raw.githubusercontent.com/ios122/graph-go/master/data.js

可视化原理

主要涉及一下内容:

  • 可视化显示,使用的是 echarts

  • 使用原始数据的 ImportPath 而不是 Name,来作为每个数据节点的唯一id.这样是因为 golang 本身的包命名规范决定的.

  • 使用原始数据的 Imports 字段,来确定标准库包与包之间的相互依赖关系.golang是不允许循环依赖的,所以一些循环依赖相关的问题,不需要考虑.

  • 节点的大小,和包被其他包引入的次数成正相关.这样做,被依赖越多的包,图上最终显示时,就会越大.常用包和不常用包,一目了然.

数据整理

就是把原始数据,处理成 echarts 需要的数据,这里简要说下最核心的思路:

  • echarts 显示相关的代码,很大程度上参考了 graph-npm

  • 节点坐标和颜色,采用随机坐标和颜色,以去除节点和包之间的联系.我认为这样处理,能更纯粹地观察标准库包与包之间的联系.

  • 需要一个 edges 来记录包与包之间的依赖关系.在每次遍历 Imports 时,动态写入.

  • 需要一个 nodes 来记录包自身的一些信息,但是其 size 参数,需要计算过所有依赖关系后再填入.

  • 使用 nodedSize 来记录每个包被依赖的次数,为了提升效率,它是一个字典Map.

 /* 将原始数据,转换为图标友好的数据.
ImportPath 作为唯一 id 和 标签;
Imports 用于计算依赖关系;
节点的大小,取决于被依赖的次数;
*/
function transData(datas){
/* 存储依赖路径信息. */
let edges = [] /* 存储基础节点信息. */
let nodes = [] /* 节点尺寸.初始是1, 每被引入一次再加1. */
let nodedSize = {} /* 尺寸单位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
}
})
}
}) /* 尺寸数据合并到节点上. */
nodes.map((item)=>{
let itemId = item.id
if(nodedSize[itemId]){
item.size = nodedSize[itemId]
}
}) return {
nodes,edges
}
}

效果与源码

相关链接

golang 标准库间依赖的可视化展示的更多相关文章

  1. Golang 标准库log的实现

      原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://gotaly.blog.51cto.com/8861157/1406905 前 ...

  2. golang标准库分析之net/rpc

    net/rpc是golang提供的一个实现rpc的标准库.

  3. Golang 标准库提供的Log(一)

      原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://gotaly.blog.51cto.com/8861157/1405754 G ...

  4. golang 标准库

    前言 不做文字搬运工,多做思路整理 就是为了能速览标准库,只整理我自己看过的...... 最好能看看英文的 标准库 fmt strconv string 跳转 golang知识库总结

  5. golang标准库 context的使用

    本文索引 问题引入 context包简介 示例 问题引入 goroutine为我们提供了轻量级的并发实现,作为golang最大的亮点之一更是备受推崇. goroutine的简单固然有利于我们的开发,但 ...

  6. Golang标准库——io-接口

    接口 Read相关 Reader Reader接口用于包装基本的读取方法. type Reader interface { //将数据读入到p中,直到读满p或者读取的过程中遇到错误,此时返回的n< ...

  7. Golang标准库——io-结构

    结构 LimitedReader 定义 限制从Reader中读取的字节数. type LimitedReader struct { R Reader // underlying reader N in ...

  8. golang 标准库 sync.Map 中 nil 和 expunge 区别

    本文不是 sync.Map 源码详细解读,而是聚焦 entry 的不同状态,特别是 nil 状态和 expunge 状态的区分. entry 是 sync.Map 存放值的结构体,其值有三种,分别为 ...

  9. golang标准库中有些函数只有签名没有函数体是怎么回事?

随机推荐

  1. Centos 7服务启动文件

    在Centos 7中,如果要编辑一个脚本服务文件,并使用systemd进行管理,则必须将服务文件命名为/etc/systemd/system/*.service. service unit文件中的选项 ...

  2. [js高手之路]深入浅出webpack教程系列8-(postcss-loader,autoprefixer,html-loader,less-loader,ejs-loader)用法

    我们接着上文,那么在上篇文章的最后,写到了css-loader的用法,如果你用心发现,就能看到我在style.css样式文件中写了一个这样的样式: div { transition: all ease ...

  3. setTimeout和setInterval不容易注意到的一些细节

    今天没事翻了翻JS高程,看到了setTimeout部分有这么一句话:调用setTimeout()之后,该方法会返回一个数值ID,表示超时调用.这个超时调用ID是计划执行代码的唯一标识符,可以通过它来取 ...

  4. 基于NIOS-II的示波器:PART2 界面动态显示功能

    本文所有的硬件基础以及工程参考来自魏坤示波仪,重新实现驱动并重构工程. version 0.2 界面动态显示功能 界面显示功能原理 显示波形有如下两个方案: 每一帧直接重绘显示界面,再显示下一帧图形 ...

  5. JS中event.keyCode用法及keyCode对…

    js中event.keyCode用法及keyCode对照表 标签: javascriptJavaScriptJavascriptjavaScript 2012-12-11 15:11 HTML Jav ...

  6. 结对编程1 —— 基于GUI和Swing的四则运算题目生成器

    合作伙伴 201421123102 王艳秋 201421123106 陈 雄 代码地址 题目描述 我们在个人作业1中,用各种语言实现了一个命令行的四则运算小程序.进一步,本次要求把这个程序做成GUI( ...

  7. 团队作业4——第一次项目冲刺 fOURth DaY

    项目冲刺--Quadra Kill 兄弟们,再坚持一下,再坚持一下,再给我一个头我就五杀了. 今天可谓是项目的一个转折点,因为跳转和数据库已经基本写好啦,鼓掌~[啪啪啪啪啪啪] 让我们来看看今天大家做 ...

  8. 201521123012 《Java程序设计》第七周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 参考资料: XMind 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代 ...

  9. 201521123112《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点 1.2 可选:使用常规方法总结其他上课内容 课上讲了一些Markdown的用法,包括分割线.参考链接.代码引入等等. 2. 书面 ...

  10. 201521123030《Java程序设计》 第2周学习总结

    本周学习总结 String常量,创建之后不能再进行修改 使用+连接字符串会产生新字符串,要大量使用重复性连接应用StringBuilder,检测字符串相等应用equal方法. 枚举类型变量的取值在一个 ...