柳海燕
(蘇州工業(yè)園區(qū)職業(yè)技術(shù)學(xué)院,江蘇 蘇州 215123)
React是Facebook于2013年開源的用于構(gòu)建用戶界面的框架,現(xiàn)在隨著React可以使用Node進(jìn)行服務(wù)器渲染以及使用React Native開發(fā)原生移動(dòng)應(yīng)用功能的豐富,使得它現(xiàn)在成為Web開發(fā)的主流工具之一。
Recharts是2016年阿里巴巴前端團(tuán)隊(duì)開發(fā)的一款可視化組件庫(kù),用React進(jìn)行設(shè)計(jì),重新定義了組合與配置方式,官網(wǎng)為http://recharts.org。最初為了國(guó)際化發(fā)展官方只提供了英文文檔,所以,國(guó)內(nèi)用戶數(shù)量增長(zhǎng)相比國(guó)外慢很多。大部分同行還是使用百度的Echarts進(jìn)行數(shù)據(jù)展示,崔蓬[1]在2019年探索了基于ECharts平臺(tái)的可視化開發(fā)方法。當(dāng)然,針對(duì)不同的語(yǔ)言與開發(fā)環(huán)境,也有其他不同的數(shù)據(jù)可視化方法。比如,寇國(guó)釗等[2]在2019年介紹了基于Java技術(shù)的開源動(dòng)態(tài)圖表開發(fā)組件JFreeChart。賈麗娟等[3]在2019年借助Python強(qiáng)大的數(shù)據(jù)處理和分析技術(shù),將數(shù)據(jù)轉(zhuǎn)化為PyEcharts組件接口參數(shù),實(shí)現(xiàn)由數(shù)據(jù)到可視化圖表的轉(zhuǎn)換。但由于大小、語(yǔ)言、顯示問題,上述都不是React框架的最佳選擇。
Recharts當(dāng)前包含了中文、英文兩種文檔,在方便國(guó)際化的同時(shí),也友好地滿足了本土化的需求。除了阿里指數(shù)、阿里數(shù)據(jù)兩個(gè)忠實(shí)用戶外,還有很多外國(guó)公司,如Fyndiq,Ahrefs等都在使用,相信隨著React用戶數(shù)量的增長(zhǎng),Recharts的應(yīng)用前景也越來(lái)越廣闊。本文嘗試在React框架中引入Recharts進(jìn)行數(shù)據(jù)可視化顯示。
官方推薦使用npm的方式進(jìn)行安裝,能更好地和CommonJS打包工具配合使用,命令為$ npm install recharts。
在實(shí)踐的過(guò)程中,npm更新會(huì)帶來(lái)版本問題。由于Yarn是Facebook發(fā)布的一款取代npm的管理工具,Rechats是基于React開發(fā)的,所以,筆者推薦可以嘗試用yarn安裝,安裝命令為 yarn add recharts。安裝成功后,會(huì)顯示Recharts的當(dāng)前版本信息。
首先,要選擇所需要的圖表類型,當(dāng)前Recharts提供的圖表有AreaChart,BarChart,LineChart等11種類型,用戶可根據(jù)自己的應(yīng)用需要進(jìn)行選擇。其次,通過(guò)import添加所需要的組件。最后,根據(jù)組件屬性來(lái)使用組件進(jìn)行顯示,甚至自定義組件,來(lái)實(shí)現(xiàn)定制化的功能。
根據(jù)所開發(fā)應(yīng)用的需要,采用Recharts中PieChart圖表類型來(lái)顯示數(shù)據(jù)。用到了PieChart的子組件Pie和Pie的子組件Cell,通過(guò)其fill屬性來(lái)傳遞數(shù)據(jù)項(xiàng)對(duì)應(yīng)子節(jié)點(diǎn)的配置。通過(guò)Pie組件的data屬性來(lái)存放源數(shù)據(jù),通過(guò)Pie組件的label屬性來(lái)展示圖形上的文本標(biāo)簽。當(dāng)然,所需組件事先需要通過(guò)import語(yǔ)句來(lái)引入。
通過(guò)Pie組件的label屬性來(lái)展示圖形上的文本標(biāo)簽,只不過(guò),label的值寫成一個(gè)函數(shù)renderLabel,用該函數(shù)來(lái)渲染自定義的文本標(biāo)簽。圖形顯示部分主要源代碼如下:
data={visitList} dataKey="value" nameKey="label" cx={200} cy={200} labelLine={false} label={this.renderLabel} fill="#8884d8" > {visitList.map((entry, index) =>
可以看到,此時(shí),Pie的label屬性就是前面自定義的函數(shù)renderLabel,使得圖像按照需要進(jìn)行內(nèi)容顯示。
React通過(guò)路由庫(kù)React-Router,管理URL,實(shí)現(xiàn)組件的切換和狀態(tài)的變化。在本應(yīng)用中,通過(guò)Route來(lái)指定路徑對(duì)應(yīng)的組件,此統(tǒng)計(jì)顯示的代碼為
圖1 正常顯示的圖表
當(dāng)單擊圖中其他菜單,比如,“訪問申請(qǐng)”“權(quán)限管理”后,再次單擊“申請(qǐng)統(tǒng)計(jì)”菜單時(shí),Pie組件的label并不顯示,只有圖形,沒有圖形上的標(biāo)注文字。因?yàn)閳D表是按照份額計(jì)算了之后正常顯示的,只是沒有上面的標(biāo)注。當(dāng)嘗試刷新頁(yè)面時(shí),數(shù)據(jù)又能正常顯示。
既然Recharts只是負(fù)責(zé)根據(jù)數(shù)據(jù)繪制圖形,且已經(jīng)繪制完成,Recharts的label屬性在刷新之后也能夠顯示文本,沒有多余的屬性來(lái)改變這一切,那就從React的角度來(lái)嘗試解決這一問題。
既然每次強(qiáng)制刷新都可以使得數(shù)據(jù)正常顯示,那么可以在React的所有路由組件共用的底層接口組件Router上使用其forceRefresh屬性,因?yàn)镽outer是路由規(guī)則制定的最外層容器,所以,每次單擊菜單鏈接時(shí),都會(huì)強(qiáng)制刷新,圖表每次可以正常顯示。
雖然解決了Recharts圖表顯示問題,但代價(jià)較大。其他所有路由都會(huì)受到強(qiáng)制刷新的牽連,所以,犧牲了應(yīng)用程序執(zhí)行效率。
為了彌補(bǔ)方案一的不足,考慮不讓所有的路由強(qiáng)制更新,每次只有單擊 “申請(qǐng)統(tǒng)計(jì)”菜單所需路由的時(shí)候再?gòu)?qiáng)制刷新。這時(shí),可以利用React中極其特殊的key屬性,雖然它不是給開發(fā)者用的,是給React自己使用的,但根據(jù)相同key的組件,React認(rèn)為是同一個(gè)組件的特點(diǎn),如果render顯示圖表時(shí)候,發(fā)現(xiàn)key不同了,那么每項(xiàng)都會(huì)重新銷毀然后重新創(chuàng)建,性能開銷要小很多。
于是,通過(guò)隨機(jī)函數(shù)隨機(jī)生成key的值,每次調(diào)用時(shí)key值不同,React就會(huì)重新渲染頁(yè)面,圖表確實(shí)可以正常顯示,且性能開銷比方案一小很多。
本文闡述了筆者在通過(guò)React框架開發(fā)應(yīng)用過(guò)程中使用Recharts的過(guò)程,遇到的問題以及解決方案,希望能夠?yàn)橥瑯酉胍赗eact中引用Recharts進(jìn)行數(shù)據(jù)顯示的同行起到拋磚引玉的作用。