您的位置:3983金沙网站在线平台 > 疾病 > golang 标准库间依赖的可视化展示

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

发布时间:2019-11-26 15:11编辑:疾病浏览(198)

    效果与源码

    • github 源码:
    • echarts 在线预览:

    简介

    图片 1

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

    以下内容,数据源自真实环境的 golang 1.9 版本的标准库.所以,本文不仅是一篇可视化相关的讨论文章,更是提供了一个可以直接探究 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
      }
      

      }

    可视化原理

    主要涉及一下内容:

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

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

    • 使用原始数据的 Imports 字段,来确定标准库包与包之间的相互依赖关系.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"
        ]
    }
    

    梳理过的数据源,参见:

    相关链接

    • echarts
    • graph-npm

    本文由3983金沙网站在线平台发布于疾病,转载请注明出处:golang 标准库间依赖的可视化展示

    关键词: