超好用的命令列圖表庫 - tcharts.js

螞蟻金服資料體驗技術發表於2017-11-16

作者簡介 hustcc 螞蟻金服·資料體驗技術團隊

我們開發使用的很多工具都是 cli 工具,比如 babel,eslint,webpack,jest 等等。控制檯因為其特殊性,它的資訊表現力僅在於一個一個單純的字元。

控制檯的字元圖表可以有效提高資料視覺化能力,提高資訊接收的效率,也更加美觀。例如:

/**
 * 柱形圖
 *
 * ^
 * |    A:70
 * |   +---+
 * |   |   |
 * |   |   |              C:50
 * |   |   |             +---+
 * |   |   |             |   |
 * |   |   |     B:30    |   |
 * |   |   |    +---+    |   |
 * |   |   |    |   |    |   |
 * |   |   |    |   |    |   |
 * |   |   |    |   |    |   |
 * +---+---+----+---+----+---+----->
 *
 */
複製程式碼

快槍手快速開始:github.com/ProtoTeam/t…

一、介紹

目前很多的控制檯應用,能夠做到顏色和簡單的動畫,來讓資料顯示更清晰、美觀,舉個例子:

超好用的命令列圖表庫 - tcharts.js

以上是某一個簡單專案 uri-parse 的單測結果在控制檯的展現效果,已經非常美觀清晰了。

但是對於某些資料的展現,僅僅只是顏色上的美化,並不能有很好的效果,比如:

超好用的命令列圖表庫 - tcharts.js

以上是兩個程式碼進行 benchmark 跑分的效果。其實如果不是限制在控制檯上,我們都希望:這種跑分結果使用一個**柱形圖**來給出一個相對比較,這樣更加直觀。

二、做什麼

我們要做什麼?很明確,我們要做一個控制檯下面的圖表庫。

想到圖表庫,我們應該很容易想到 echarts、G2 等等,這樣圖表庫的執行環境是在瀏覽器,可以充分利用 canvas、SVG、css 來做出各種佈局、樣式、特效,吊得不行!

先放一個圖:

超好用的命令列圖表庫 - tcharts.js
截圖自:github.com/chartjs/Cha…

對於控制檯環境,我們可以做些什麼圖形呢?我大概列舉幾個:

  • Table:表格
  • Bar:柱形圖
  • HBar:橫向柱形圖
  • Box:面積圖
  • DirTree:目錄結構圖

以上是我能想到的一些應用例項。

三、怎麼做?

最終實現的是一個可以使用的的控制檯圖表庫,但是可能並不完美!

約定

為了做到以上的幾個控制檯圖表,並且**提高圖形的在不同環境控制檯的適配能力**。約定:

  • 圖形僅僅使用基本字元繪製(鍵盤上的字元)
  • 不使用顏色(部分控制檯並不支援顏色,同樣也簡化程式碼)
  • 取名叫 tcharts 吧:terminal charts。

原理

先給大家講一個例子,現在玩手遊的人很多,手遊釋出上線之前會送廣電局稽核,稽核中有一點就是遊戲中角色的衣服是否存在裸露(漏電)。遊戲在製作的時候,會現有角色的 3D 模型,然後在角色上掛上一層衣服,這個就是收費點——皮膚。

有些時候,美術做出來的皮膚掛到某些人物身上的時候,因為皮膚尺寸小了,或者角色胸太大了,導致裸露,這種情況下,遊戲就很可能不能通過稽核了!

這個例子中,其實大家可以感受到**圖層**的概念,就是一個角色在遊戲中的渲染會有很多層次結構,但是終端使用者看到的,其實就是最上面的一層。

類似的,在 HTML div 佈局的時候,當結構有層疊的時候,可以通過 z-index 調整層次結構,讓使用者看不到不同的東西。

類似的,瀏覽器的圖表庫也會有圖層的概念,一層一層疊加覆蓋起來,形成終端使用者看到的圖形!

控制檯圖表 tcharts.js 開發的基本原理也是分不同的圖層,好處在於:

  • 圖層複用容易;
  • 擴充套件圖表型別容易;
  • 程式碼更清晰;

當然缺點在於 重複繪製

比如最上面的一個柱形圖,我們可以按照圖層的思路,可以分成為兩種圖層:

  • Axis:座標軸
  • Rect:矩形

也就是上面的柱形圖可以拆分成四層:

1 層 Axis

    ^
   |
   |
   |
   |
   |
   |
   |
   |
   |
   |
   +---+---+----+---+----+---+----->
複製程式碼

3 層 Rect

       +---+
       |   |
       |   |
       |   |
       |   |
       |   |
       |   |
       +---+
複製程式碼

然後還可以細分,Axis 分成 2 條 Line,加座標 Point;Rect 就直接可以拆分成 4 條 Line。

這樣一層一層遞迴下去,最終實際工作的,就是在每一個對應的座標點,繪製一個點。當所有的點繪製完畢之後,整個圖也就顯示出來了。

四、tcharts.js

總體來說基本原理就是:

                        Point
                          |
                        Line
                        /  \
           Text   +   Rect   Axis
              \       /  \     |
               RectText    \   |
                    \      |   |
                Bar / HBar / Table / Box
複製程式碼

從 點 -> 線 -> 面,一層一層擴充套件圖形,然後引入 Layer(圖層)來組裝這些元素,最終通過圖層的合併,生成最終的圖形。

tcharts.js 整個專案的類圖結構如下圖所示(其實程式碼量很小,讀起來應該不難懂!):

目前匯出 4 個圖形!

超好用的命令列圖表庫 - tcharts.js

整個專案程式碼檔案的依賴關係為(使用 webstorm 生成,無法刪除一些不必要的連線):

超好用的命令列圖表庫 - tcharts.js

程式碼在這裡:github.com/ProtoTeam/t…。時間原因,目前只完成了 4 個圖表,不過後續的擴充套件應該不難,程式碼上也欠優化,希望歡迎大家參入進來。

發幾個效果出來(可能在某些頁面 css 下面,導致沒有完全對齊!):

    +--------------+----------------------+---------------------+
    |              |                      |                     |
    |              |                      |                     |
    |              |                      |                     |
    |              |                      |                     |
    |              |                      |                     |
    |              |                      |                     |
    |              |        C:25%         |      Hello:25%      |
    |              |                      |                     |
    |              |                      |                     |
    |    A:25%     |                      |                     |
    |              |                      |                     |
    |              |                      |                     |
    |              +----------------------+---------------------+
    |              |                                            |
    |              |                                            |
    |              |                                            |
    |              |                   B:25%                    |
    |              |                                            |
    |              |                                            |
    +--------------+--------------------------------------------+


    ^                                                      
    |                                                      
    +---------------+                                      
    |           D:30|                                      
    +---------------+                                      
    |                                                      
    +------------------------------------+                 
    |                                C:70|                 
    +------------------------------------+                 
    |                                                      
    +-----------------------+                              
    |                   B:45|                              
    +-----------------------+                              
    |                                                      
    +----------------------------------------------------+ 
    |                                               A:100| 
    +----------------------------------------------------+ 
    |                                                      
    +----------------------------------------------------->


    +----+---------------+--------------------+
    | id |      name     |      birthday      |
    +----+---------------+--------------------+
    | #1 |    xiaowei    |     1992-08-01     |
    +----+---------------+--------------------+
    | #2 |     hello     |     1992-09-20     |
    +----+---------------+--------------------+
    | #3 |    tcharts    |     2017-06-27     |
    +----+---------------+--------------------+
    | #4 |     world     |                    |
    +----+---------------+--------------------+
複製程式碼

對tcharts感興趣的同學可以關注專欄或者傳送簡歷至'xiaowei.wzw####alibaba-inc.com'.replace('####', '@'),歡迎有志之士加入~

原文地址:github.com/ProtoTeam/b…

相關文章