golang 标准库间依赖的可视化展示。Golang标准库间依赖之可视化展示。

golang 标准库间依赖的可视化展示。Golang标准库间依赖之可视化展示。

简介

图片 1

国庆拘留了 << 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是免同意循环依赖的,所以部分循环依赖相关的题目,不需要考虑.

  • 节点的轻重,和包被外保险引入的次数成正相关.这样做,被因越多之包,图上最后显示时,就会愈发大.常用包和免常因此包,一目了然.

国庆扣了 << Go 语言圣经
>>,总想做点啊,来深化下印象。以可视化的办法展示 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.9
版本的专业库.所以,本文不仅是如出一辙首而视化相关的座谈文章,更是提供了一个足直接追究
golang 标准库间依赖关系之快捷梳理工具。

意义和源码

  • github 源码: https://github.com/ios122/graph-go
  • echarts 在线预览:
    http://gallery.echartsjs.com/editor.html?c=xSyJNqh8nW

图片 2

有关链接

  • echarts
  • graph-npm

数码准备

标准库各个包中的相互关系,可以一直通过命令获取,然后简单转换为一个正经的
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     } } 

作用及源码

  • github 源码: https://github.com/ios122/graph-go
  • echarts 在线预览:
    http://gallery.echartsjs.com/editor.html?c=xSyJNqh8nW

【编辑推荐】

admin

网站地图xml地图