摘要:是年初團隊可視化組推出的一款可視化組件庫,為基礎(chǔ)表格的繪制提供了另外一種可能。為方便國際化,文檔只有英文官網(wǎng),中文官網(wǎng)還在編寫中。如果試用有問題,歡迎給項目提請使用英文來提,謝謝。
Recharts 是 2016 年初團隊可視化組推出的一款可視化組件庫,為基礎(chǔ)表格的繪制提供了另外一種可能。
Recharts 含義是重新定義(Redefined)圖表。這個名字的背后在于這個圖表在設(shè)計上帶給開發(fā)者的是不一樣的體驗,不僅是用 React 設(shè)計,也在于重新定義了組合與配置方式。
Recharts 到今天的版本是 0.9.3,支持 React 0.14.x 或 15.0.x 版本,現(xiàn)在有至少四個國外團隊在產(chǎn)品中使用。為方便國際化,文檔只有英文官網(wǎng) Recharts,中文官網(wǎng)還在編寫中。如果試用有問題,歡迎給項目提 issue(P.S. 請使用英文來提,謝謝)。
接下來我們會從思想層面來剖析 Recharts 的原理和精髓。
大家可以回顧一下在做圖表類的需求時,碰到最糾結(jié)的問題是什么?這里列了一些我碰到最多的問題:
配置非常復雜,可配置的內(nèi)容太多,找不到到底使用什么配置項來達到想要的目的
很多樣式無法完全統(tǒng)一,變化很多。這個線圖怎么多了條線?這個柱圖的“柱子”怎么是個三角形?
那 Recharts 是怎么解決這些問題呢?
聲明式的標簽,讓寫圖表和寫 HTML 一樣簡單
貼近原生 SVG 的配置項,讓配置項更加自然
接口式的 API,解決各種個性化的需求
下面我們將仔細分析這些是怎么實現(xiàn)的。
聲明式的標簽在看代碼實現(xiàn)之前,我們先看看怎樣一步步的根據(jù)各自的需求創(chuàng)建一個線圖:
首先,通過調(diào)用 LineChart 添加一條 dataKey 為 pv 的 Line:
const data = [{ name: "a", uv: 4000, pv: 2400 }, { name: "b", uv: 3000, pv: 1398 }, ....];
運行代碼后結(jié)果如下:
然后,我們可以根據(jù)自己的需求去豐富這個線圖,比如這個線圖需要一個 X 軸和 Y 軸,那只需要在 LineChart 下添加一個 XAxis 和 YAxis 標簽即可:
const data = [{ name: "a", uv: 4000, pv: 2400 }, { name: "b", uv: 3000, pv: 1398 }, ....];
運行代碼結(jié)果如下:
大家看到用 Recharts 繪制圖表很多時候就想拼積木一樣,那 LineChart 內(nèi)部是如何去識別這些『零件』的呢?我們先來看一個簡單的函數(shù):
const getDisplayName = (Comp) => { if (!Comp) { return ""; } if (typeof Comp === "string") { return Comp; } return Comp.displayName || Comp.name || "Component"; };
這個方法很簡單,可以用來讀取某個 ReactComponent 的名稱。在 LineChart 的代碼實現(xiàn)中,就是根據(jù) ReactComponent 的 displayName 來識別所有的 Children。我們先來看一個工具方法:
const findAllByType = (children, type) => { const result = []; let types = []; if (_.isArray(type)) { types = type.map(t => getDisplayName(t)); } else { types = [getDisplayName(type)]; } React.Children.forEach(children, child => { const childType = child && child.type && (child.type.displayName || child.type.name); if (types.indexOf(childType) !== -1) { result.push(child); } }); return result; };
這里 type 可以是 ReactComponent 或者 ReactComponent 數(shù)組。而 LineChart 內(nèi)部實現(xiàn)的時候就是調(diào)用這個方法來識別各個『零件』:
... render() { const { children } = this.props; const lineItems = findAllByType(children, Line); ... }貼近原生的配置項
圖表的配置項可以非常多,但是有很多配置項如填充顏色、描邊顏色、描邊寬度等等這些都是SVG標簽原生就支持的屬性,為了減小大家的配置的成本,Recharts 的組件會去解析原生的屬性。舉個例子,一個線圖里面有兩條曲線,我想給一條曲線設(shè)置成虛線,一條設(shè)置成實線,我們只需要像原生的 SVG 元素一樣設(shè)置 stroke-dasharray 屬性就行:
const data = [{ name: "a", uv: 4000, pv: 2400 }, { name: "b", uv: 3000, pv: 1398 }, ....];
結(jié)果如下:
實現(xiàn)原理也比較簡單,首先 Recharts 內(nèi)部維護一份 SVG 元素支持的所有屬性,然后在渲染 SVG 元素之前,我們會去解析相應(yīng)的ReactElement的 props,看看哪些是 SVG 元素能夠支持的屬性,最終這些屬性可以傳入到渲染的 SVG 元素中。
const PRESENTATION_ATTRIBUTES = { fill: PropTypes.string, strokeDasharray: PropTypes.string, ... }; const getPresentationAttributes = (el) => { if (!el || _.isFunction(el)) { return null; } const props = React.isValidElement(el) ? el.props : el; let result = null; for (const key in props) { if (props.hasOwnProperty(key) && PRESENTATION_ATTRIBUTES[key]) { if (!result) {result = {};} result[key] = props[key]; } } return result; };
接口式的 API關(guān)于更多SVG屬性,大家可以參考W3C標準文檔
很多時基礎(chǔ)圖表往往不能滿足所有的要求,那怎么去滿足各種個性化的需求成了圖表組件必須要考慮的事情。
Recharts 對可能會變化的元素都提供了自定義的接口,以x軸的刻度為例,普通的刻度就是一些文字,在信息圖表中,為了讓圖表更佳的生動,視覺往往希望能夠?qū)⑽淖痔鎿Q成形象的 icon。
對于這種自定義的需求,Recharts 提供了兩種方式,第一種是通過 React Element 的方式:
const CustomizedTick = (props) => { const { x, y, payload, bgColor, index } = props; return (); }; {index} }/>
通過將 tick 設(shè)置成一個 React Element,在拿到內(nèi)部 props 的同時,也可以非常方便的從外部傳入 props。
第二種自定義的方式是通過 function:
const renderCustomizedTick = (props) => { const { x, y, payload, index } = props; return (); }; {index}
這種方法,renderCustomizedTick 中拿到的參數(shù)和 CustomizedTick 的 props 是一樣的,當然這種自定義的方法外部傳參數(shù)會稍微麻煩一些。
看到這里大家可能會好奇內(nèi)部是怎么去實現(xiàn)?原理也非常簡單,我們在內(nèi)部計算好 tick 的位置等信息,然后判讀 tick 參數(shù)的類型,實現(xiàn)代碼簡化如下:
let tickItem; if (React.isValidElement(tick)) { tickItem = React.cloneElement(tick, props); } else if (_.isFunction(tick)) { tickItem = tick(props); } else { tickItem ={value} ; }
看到這里大家可以發(fā)現(xiàn) Recharts 內(nèi)部主要做了計算各種 layout 的事,每個區(qū)塊具體展示什么內(nèi)容都是可以自定義的。
延伸到這里我們已經(jīng)介紹了 Recharts 實現(xiàn)可視化組件的一些核心思想,其實這些思想不只是在可視化組件中可以應(yīng)用,很多組件也可以考慮利用這種思想來實現(xiàn),例如表格組件就可以抽取 Table 和 Column 兩個組件,然后大家使用表格也非常簡單:
我們大約會在本月末,或下月初發(fā)布,
更好的動畫支持
同步文檔更新
增加一些圖表的支持
90% 的測試覆蓋率
關(guān)于無線支持可能會放到 1.0 之后再考慮,因為 SVG 對手機的兼容性支持度一般。1.0 版本之后,會切分出 React 15.x 的 Recharts。因為 15.x 對 SVG 的支持更加完善。
盡管 web 端已經(jīng)有不少優(yōu)秀的可視化庫,亦或是圖表庫,比如 Echarts,highcharts,科學界有 ggplot,他們都是可視化界的前輩。在可視化的探索上,給我們很多啟發(fā)。我們造 Recharts 的初忠是給 React 社區(qū)貢獻一個代碼更優(yōu)雅,靈活可裝卸的圖表庫的圖表庫。
感謝團隊可視化組的小伙伴。最后是安利時間,第一款使用 Recharts 的線上項目 阿里指數(shù)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79250.html
摘要:使用來呈現(xiàn)圖表。允許用戶在應(yīng)用程序中創(chuàng)建美觀的可復用的圖表。它是基于創(chuàng)建的,是一個以數(shù)據(jù)為中心的圖表庫,可以改進數(shù)據(jù)可視化的效果。非常輕巧,并使用元素來創(chuàng)建很奇特的圖表。是庫中較為古老的圖表庫之一。總結(jié)以上介紹的庫都是高質(zhì)量的圖表庫。 當前,數(shù)據(jù)可視化已經(jīng)成為數(shù)據(jù)科學領(lǐng)域非常重要的一部分。不同網(wǎng)絡(luò)系統(tǒng)中產(chǎn)生的數(shù)據(jù),都需要經(jīng)過適當?shù)目梢暬幚恚员愀玫某尸F(xiàn)給用戶讀取和分析。 對任何一個...
摘要:適用于,演示這是開發(fā)的一個簡單的可視化庫,它允許你創(chuàng)建所有常用的圖表類型條形圖,樹形圖,折線圖,面積圖等。可以輕松地對折線圖和條形圖進行混合和匹配以組合不同的數(shù)據(jù)集,這是非常棒的功能。 翻譯:瘋狂的技術(shù)宅原文:https://www.monterail.com/blo... 本文首發(fā)微信公眾號:jingchengyideng歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章 你的程序有多...
摘要:數(shù)據(jù)可視化庫超過的的可能是最流行和最廣泛的數(shù)據(jù)可視化庫。是一組組件,用于高效地渲染大型列表和表格數(shù)據(jù)。一種優(yōu)雅而靈活的方式,可以利用組件來支持實際的數(shù)據(jù)可視化。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! React Native 組件庫 1. NativeBase showImg(https://segmentfault.com/img/bVbrLHH?w=...
摘要:在業(yè)務(wù)統(tǒng)一的情況下,僅僅修改組件用于配置的就可以滿足業(yè)務(wù)需求。避免了復雜的圖表配置,而將圖表進行有效拆分,通過聲明式的標簽進行組合,從而使圖表更具擴展性。而對于顆粒度最細的組件,我們希望它是純粹的,木偶式的組件。 在前端業(yè)務(wù)開發(fā)中,組件化已經(jīng)成為我們的共識。沉淀和復用組件,是提高開發(fā)效率的利器。但在組件復用的過程中,我們往往會遇到這樣的問題,組件相似,卻在結(jié)構(gòu)或交互上有些許差別,需要對...
摘要:也是一款優(yōu)秀的響應(yīng)式框架站點所使用的一套框架為微信服務(wù)量身設(shè)計的一套框架一組很小的,響應(yīng)式的組件,你可以在網(wǎng)頁的項目上到處使用一個可定制的文件,使瀏覽器呈現(xiàn)的所有元素,更一致和符合現(xiàn)代標準。 GitHub 值得收藏的前端項目 整理與收集的一些比較優(yōu)秀github項目,方便自己閱讀,順便分享出來,大家一起學習,本篇文章會持續(xù)更新,版權(quán)歸原作者所有。歡迎github star與fork 預...
閱讀 1040·2019-08-30 12:57
閱讀 2114·2019-08-30 11:11
閱讀 2177·2019-08-29 15:20
閱讀 1870·2019-08-29 14:12
閱讀 3274·2019-08-28 17:51
閱讀 2378·2019-08-26 13:23
閱讀 789·2019-08-26 10:34
閱讀 3844·2019-08-23 12:37