舊坑還沒填,我又來挖新坑了
暫時是打算把<use>以外的圖形元素都先支持了。然後再這些基本圖形的基礎上,再做組合,來做更複雜的事情,比如畫圖表啊,畫圖表啊還有畫圖表啊……
當然,這種庫歷史上已經夠多了,除了d3和構建在d3之上的各種chart方案之外,還有recharts和react-d3這種框架限定的方案。(相比之下,我更喜歡recharts那種依靠平台的表現力來簡化學習成本的方案,d3本身包含巨複雜的dom操作,d3的插件們往往需要使用者配置炒雞巨大的config對象)
前一段時間我也在嘗試用vue來實現一個好用又靈活的chart方案,然而由於各種原因爛尾了……如果誰有興趣做下去,可以參考下這個repo:GitHub - Twiknight/vue-bricks: vue svg components toolkit。
(在此聲明,這個坑我絕對不會填了,因為新的庫可以很輕鬆的port到絕大多數平台,再填這種坑毫無意義)
這次的玩具和我見過的大多數chart解決方案都不太一樣,不同主要在於以下兩點:
- 利用ramda的curry特性來實現復用,不再需要巨大的配置文件。自定義的組件需要自己寫函數來實現。這個做法看起來很激進,實際上考慮到我們記住各種配置項的巨大學習負擔,個人認為還是挺划算的。而且所謂的寫函數實現也就是下面這種函數:
const horizLine = createLine({ stroke:red}, 0, 100, 100, 100)nconst verticLine = rotate(line, 90)nconst blueLine = compose(moveEndTo(__, 200, 200), setAttr(__, stroke,red))(verticLine)nnconst lineDom = compose(createDOM, portLine)nconst lineVueComp = compose(createVUE, portLine)nconst lineVNode = compose(createVNode, portLine)n
個人認為無論是從復用的角度還是從可讀的角度來說,都比配置一個炒雞大的config來得要強點。雖然習慣ramda和curry-function需要一段時間。(沒關係,我寫代碼也得開著ramda的文檔,畢竟非fp專精的程序員很難想起來那一票函數都叫啥
- 通過一個簡化的中間對象(基本上是hyperscript參數組成的)為過渡然後port到所有平台,這樣我就不用考慮我為Vue寫的組件怎麼才能在cycle上用這種問題了。(當然能不能port到elm我沒考慮過,理論上來說,我只要port到evancz大神的virtual dom實現上就算大功告成了)當然,這個點子實在是太普通了,virtual dom就是這麼乾的,不過造SVG庫的好像還沒有人這麼干(也許是我孤陋寡聞,如果有請務必告訴我)。本來的想法也是直接借用某個virtual dom實現,不過這樣有兩個缺點: 1. 不同的virtual dom介面不一樣……雖然Vnode的結構都差不多,但是顯然都比直接基於hyperscript參數的中間對象要複雜。2. 如果我想port到react或者Vue,virtual dom自帶的那一套更新機制就顯得很雞肋。如果一開始只是用VNode,而不要更新機制……那我用vdom增加自己管理依賴的負擔幹嘛。
當然,問題還有很多,比如:
- 我自己並不會FP,所以我用ramda寫的代碼現在挺爽,以後會不會成為大坑……
- 雖然我很想把所有操作弄成pure function,奈何得提醒參數錯誤, 所以相當於所有function都有副作用……解決方法也有,直接上Either,最後render的時候決定要不要warn。但是這樣的話,使用者在自定義一些東西的時候,也必須引入fantasy,操作數據也沒有那麼方便,所以還在考慮中。目前的想法是在prototype版本中一部分元素用plain object,一部分上fantasy,然後自己試試好不好使(講真,我是真的很討厭到處都是isValidXXX, isXXXLike這種函數,然而為了讓使用者安全的用自己的代碼在任何地方替換我的代碼,也只能這樣了;當然,如果有fantasy那就是另一回事了,不開心了我直接返回Left或者Nothing就好)
- Type System到底要不要,目前做法是在Object裡面帶一個Type屬性,然後寫上 line, rect, circle之類的,當然,也可能引入flow或者typescript(也可能是purescript,雖然可能性比較小)……不過在prototype版本中應該還不會做這些事情。
- 我這個人太懶了(最近失業在家變得更懶了,sigh,本來以為不用上班會好好寫代碼的),所以我才會在prototype完成度不到一半的時候把這個文章發出來。怕萬一坑了被打臉也算是動力的一種吧。所以覺得這個玩意有點意思的朋友,請不用客氣,猛烈地催更。
- 當然,肯定會有更多問題隨著項目的進展而出現……
最後,預計這周末或者下周可以拿出一個勉強可用的prototype版本出來,可能會帶有一兩個port到SVG DOM的例子。
如果有朋友覺得這個小玩具有點意思希望了解更多,或者覺得作者太傻逼我要教他做人,歡迎私信我;公開撕逼也是歡迎的,我的心理素質(lian pi)足夠強大 _(:3 」∠ )_ (逃
推薦閱讀: