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