golang 標準庫間依賴的可視化展示

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

簡介

國慶看完 << 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    }}

效果與源碼

  • github 源碼: https://github.com/ios122/graph-go
  • echarts 線上預覽: http://gallery.echartsjs.com/editor.html?c=xSyJNqh8nW

相關連結

  • echarts
  • graph-npm
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.