作者簡介 Kid 螞蟻金服·資料體驗技術團隊
本文介紹如何從頭繪製一個業務圖表以及對於通用性上的一些思考。程式碼在最後也會給出。
效果演示
先看下元件的最後效果
要畫圖,當然是先找找看有沒有能夠直接拿來用的。我需要繪製的是一個類甘特圖。主要是為了做時間基線上的任務耗時管理,並且能夠與過往耗時進行對比。與傳統的甘特圖定義有些區別。長相上與甘特圖類似。
找了AntV,echarts,和D3。AntV和echarts都沒有直接的甘特圖。D3上有一些甘特圖,但是和我想要的功能區別還是挺大的。基於他們修改的代價應該比自己畫的代價高。那麼挑哪種技術繪圖呢,canvas,svg和div。我的業務場景繪製的點不算多,而且canvas對於事件挺難處理的。svg畢竟有DOM元素,一些hover效果我可以直接借用antd來做。最後選擇了svg。(其實之前沒畫過圖,用啥都得學~)
功能列表
- 圖表繪製
- 上下滾動
- 漫遊器控制左右滾動以及縮放比例
- 節點hover顯示細節
整體設計
元件結構
元件的設計就如上圖所示了。圖表與Y軸區域做成一個整體,讓圖表上下滾動。由於windows上左右滾動很不好用,所以水平方向上沒有做滾動,而是設定了漫遊器進行滾動以及縮放的功能。
資料流向
元件的資料流向很簡單,使用者傳入初始化配置以及真實資料。大部分元件只是單純負責渲染,只有漫遊器會修改圖表位置以及縮放的比例。然後圖表和X軸會相應的顯示對應區域。
結構和資料流向設計好,編碼開發其實很簡單了,不詳述,自己看github上的程式碼吧。然後就是一些細節的打磨。
細節打磨
自己從頭寫的好處就是一些小細節可以打磨的舒服些
名字滑動吸左
滑動過程中節點名字吸左顯示。
X軸放置不下隱藏
超出一定的比例之後按單雙數隱藏了X軸的部分顯示。其實既可以選擇隱藏,也可以旋轉一定的角度,自己做,隨便定~
漫遊器防抖
antv和echart漫遊器都是會抖動的,而且可拖拽區域都是隻在漫遊器內部。雖然echarts做了動畫的優化,其實還是不太舒服。截個antv的效果好了。
我把漫遊器設計成百分比的,所以滑動順滑,而且滑動的時候事件加到了document上,可拖拽區域就變成整個頁面了。
編碼做完了,細節也打磨的差不多了。對於產品的可用性已經可以交差了。也get了svg畫圖的技能,可是,沉澱下了啥呢....別人會需要繪製一模一樣的圖麼?感覺不太可能。仔細一想,自己做的東西複用性太差。那麼問題來了,複用性差跟白做了有什麼區別..
很欣賞<黑客與畫家>裡的一句話,“程式設計就跟畫油畫一樣,永遠沒有完工的那一天,你只是不再畫下去了而已”
複用性
在工程方面,可能複用性是自己一直以來比較忽視的點。但是其實思考複用性方面的問題,既是對你的設計以及程式碼質量的考驗,也能為後續的工作提高效率。還能培養你面對問題的直覺,思考複用性其實就是在思考問題的共性。這一個個共性就是一個個點,一個個的點多了,你的知識結構才能被串聯起來,形成一張網。
定義場景
如何提高複用性呢?首先明確定義業務使用場景:這個圖是為了做時間基線上的任務耗時管理,並且能夠與過往耗時進行對比。至少讓別人在相同需求的時候能夠複用,但是能重用的可能性太小了,不行。
二次開發
要不我降低二次開發的門檻?如果別人就想改一點圖表的渲染,我是不是該支援定製化渲染。仔細想想感覺不用。因為圖形繪製都改了,那離重畫一張圖也沒啥區別,畢竟技術難度也算很高。為了增加這一點靈活性,要給元件加太多的複雜度了,而且拍腦袋決定哪裡開放繪製肯定做不好。畢竟靈活性和複雜度是成正比的。為了得到一些的靈活性而需要付出的代價是非常需要權衡的。二次開發這樣的事情交給antV來做更好。
抽象通用能力
那怎麼辦?再看看能不能抽象出有一些複雜度的可重用的部分。重新審視整個設計,可用性較強的是漫遊器元件。也就是下圖內紅色虛線框的位置:
共用性的理由也很充分,畢竟windows上左右拖拽不方便是事實,圖表配上漫遊器是正常的能力,而且echarts和antv,漫遊器都沒有單獨提供。
想明白了,做其實並不難。花些時間將漫遊器的業務邏輯摘乾淨。將依賴全部以引數方式注入。然後定義好對外的介面,想想如何降低使用者的門檻。這個過程其實很能提高你的程式碼質量。你會抱怨自己為什麼最開始寫的時候沒有解耦他們。可能更好的方式不應該是做完了之後進行抽象,而是設計階段就能夠意識到這是個通用能力而在設計層面就解耦掉。
具體的漫遊器我也抽成了一個元件,如何使用可以參照我寫在github上的demo。我抽成了幾個裝飾器和一個元件,感覺已經無力再抽了,如果有好的思路能夠把他們合到一起的話歡迎告知我。
總結
文章主要是分享如何手工畫一個自定義的圖表,以及在這個過程中如何提高元件複用性來沉澱通用能力。更多的是分享下做業務元件應該去思考的角度,建議大家培養這樣的習慣。畢竟習慣這種東西很可怕,我們可以先培養出一些習慣,然後等著習慣來推動你就好了。最後放上程式碼地址,圖表地址和漫遊器地址。
對我們團隊感興趣的可以關注專欄,關注github或者傳送簡歷至'tao.qit####alibaba-inc.com'.replace('####', '@'),歡迎有志之士加入~