|
度量系统前端重构一、背景度量这类数据统计平台,基本上所有的业务逻辑都在后端,前端全部都是数据表格展示的逻辑。在本次重构需求中,涉及四种数据类型页面,共36个图表和表格,包括需求、缺陷、人员等多方面信息。每类数据生成一个页面,由不同的图表样式组成,例如散点图、柱型图、饼图等。这么多的图表,如果每个都重复的写,则开发成本就会花费在重复新建图表和表格上。如何减小这个成本是本次文章的主要目的。二、目标将前端开发成本减少到最小,并且做到能够快速实现,快速复制。三、解决方案首先我们选择Ant的图表插件:AntDesignCharts,然后根据插件的数据格式和后端约定了交互。接下来以图表和表格数据格式举例:1、接口数据格式1、图表数据:以柱型图为例,每类图通用字段由data、xField、yField、seriesField字段组成(特定图表还有其他字段)。 结构如下:const {data, xField, yField, seriesField, isStack, height}=this.props;const config = {height,data,isStack,xField,yField,seriesField};return 在这个基础上和后端约定的返回数据类型为:这四个通用字段,以及字段的对应关系全部由后端返回。那么36个图表数据就可以由一个接口根据请求类型不同返回不同数据,样例如下:实际返回值如下:获得返回的数据之后,就可以生成通用图表组件ChartCardList,统一渲染。ChartCardList组件主要内容如下:chartInfoList.map(card => { const {key = '', title = '', list = []} = card; return ( {title}}> {list.map((info, index) => { const {detail, chart, params} = info; const isShowChart = chart?.props?.data?.length || 0; const isShowDetail = detail?.data?.length || 0; return detail || chart ? ( {isShowChart ? ( {info.title}}> {chart} ) : null} {isShowDetail ? ( ) : null} ) : null; })} );});图表样例如下:2、表格数据:咱们请求数据接口是一个,参数类型不同返回不同的表格数据,如果对每个表格都声明一个表头,那么数量会很多,违背了咱们的初衷,那么就需要一个自由度很高的表头信息。声明表头结构如下:const columns =[{ title:'姓名', dataIndex:'name', key:'name',}];接口表头结构如下:data和columns数据的对应关系由后端计算好后返回。实际返回值如下:然后获取返回数据之后,前端一个简单for循环,生成通用表格组件RankTable。RankTable组件主要内容如下:a、表头组装:getColumns = (isShowDetail = true, isEllipsis = false) => { const {columns} = this.props; const columnList = []; columns.map(column => { const {key = '', title = '', link = '', sort = false} = column; columnList.push({ title, dataIndex: key, key, ellipsis: isEllipsis, sorter: isShowDetail & sort ? (a, b) => parseFloat(a[key]) - parseFloat(b[key]) : false, render: (value, row) => link === '' || typeof row[link] == 'undefined' || row[link] === '' ? value : , }); }); return columnList;}b、页面表格返回:样例如下:2、通用前端数据渲染逻辑上面介绍了数据格式的统一和最后的效果。接下来分享下公共的渲染代码。一共分为4个部分,请求数据,判断图表类型,1、约定图表代码枚举const StasticTypeEnum = { BUSINESS_INVESTMENT: 10086, HUMAN_INPUT: 10087,};2、排序页面增加图表排序枚举ChartOrderTypeEnum,决定展示的图表及顺序,内容为图表类型枚举StasticTypeEnum。图表的展示逻辑由组件统一处理。const ChartOrderTypeEnum = [{ key: 'business', title: '业务感受', list: [ StasticTypeEnum.STORY_WAIT_DELIVERY, StasticTypeEnum.DELAY_PROJECT, ] }];3、请求数据根据页面排序信息,异步请求获取数据,为每个图表类别赋值,但页面缓存顺序并非预期,需根据ChartOrderTypeEnum,再次排序。ChartOrderTypeEnum.map(order => { const { list } = order; list.map(stasticType => { getStasticDataInfo(dispatch, stasticType, selectOrgIds, selectOrgList, startTime, endTime, dateType).then(info => { this.setState(state => ({ chartInfo: { ...state.chartInfo, ...info } })); }); });});请求内容赋值: const info = { key: stasticType, title: chart.title, basic: {...basic,chart: getBasicChartItemByType(stasticType, basic)}, detail, chart: getChartItemByType(stasticType, orgIds, orgList, chart), params, }; return { [stasticType]: info };4、图表类型每类的图表展示形式不一,有些类型还是区分单业务线与多业务线,根据需求判断哪类展示哪个图表。getChartItemByType() { const isStack = seriesField != ''; const chartColumnGroup = ; if ([StasticTypeEnum.BOARD_DELIVERY_PROPORTION].includes(stasticType)) { return isMultiple ? chartColumnGroup :
; } else if ([StasticTypeEnum.HUMAN_INPUT].includes(stasticType)) { return chartColumnGroup; }}5、修改变动页面ChartOrderTypeEnum中list内容(第三步),并在StasticTypeEnum中增加枚举,getChartItemByType(第二步)中增加此类型应展示的图表类型就可以完成图表的增删改。四、效果总结1、增减图表数据时,前端只增加类型枚举和图表类型(详见三-2-5),减少开发量。2、单图表数据由后端单方面控制,字段变更后,前端无需再次确认,减少数据影响。当前方案通过统一数据格式,减少了前端开发成本,减少了前后端接口数量。前端的收益是比较可观的。后续参考quickBI等业内类似工具,提供页面定制的能力,丰富交互,进一步减少前端的开发成本,给不同角色的用户提供前端定制能力。想了解更多转转公司的业务实践,点击关注下方的公众号吧!
|
|