FVS夜光轮播仪表盘开启监控刷新,阻止组件在数据更新后重绘的方法
FVS插件版本:v11-1.3.1
FVS中目前有很多带轮播特性的组件,其在开启监控刷新 功能(即定时向后台请求更新的数据)后,在达到刷新间隔 指定的时间,向后台请求到最新的数据后,整个组件会消失,然后重新绘制组件,显示组件动画,从头开始轮播。
但我希望组件能够静默更新数据,而不是消失、重绘、播放动画、重头轮播。因为页面上组件的“闪烁”会引起关注,但这实际只是向后台请求了数据更新,并不是需要关注的事情。
而且开启监控刷新 后,刷新间隔 必须比轮播间隔 *维度数目大才行,不然就会出现轮播很没有轮播完一圈,就组件重绘,重头开始轮播的情况。这就不适用于维度数目多,又要求显示尽可能最新数据的场景。
解决方法
进入FineReport 11安装目录,然后进入目录webapps/webroot/WEB-INF/plugins/plugin-com.fr.plugin.wysiwyg.v11-1.3.1 。用压缩软件解压文件
plugin-com.fr.plugin.wysiwyg.v11-1.3.1.jar 。进入解压目录,然后进入目录com/fr/plugin/wysiwyg/web/static/js ,用文本编辑器打开文件preview.622ce744.chunk.js 。搜索:
t.chart&&(t.onDestroy(),t.onMount(t.el))
定位到以下代码:
t.chart&&(t.onDestroy(),t.onMount(t.el)),b(e,t.widget,n,t.container)
将其修改为:
t.chart,b(e,t.widget,n,t.container)
这里只是把中间要执行的(t.onDestroy(),t.onMount(t.el)) 注释掉了,这两句代码实际将仪表盘销毁,再重新生成容器元素(还没有到绘制的步骤)。这就是为什么勾选开启监控刷新 后,轮播夜光仪表盘会在达到刷新间隔 ,向后台请求数据后,整个组件消失再重绘的原因。
注释之后会发现,虽然仪表盘没有在向后台请求数据后整个消失重绘了,但仪表盘的数据也不会有变化,这是因为向后台请求的新数据没有更新到仪表盘组件中。
继续修改文件preview.622ce744.chunk.js ,搜索:
new window.Van.SliderDashboard(e)
可以定位到以下代码:
,t.dataSet.length<2?Object(Kt.i)(e,n):(e.timeInterval=n.widget.carousel.autoplaySpeed/1e3,e.container=n.container,n.chart=new window.Van.SliderDashboard(e),Object(Kt.a)(n))
其中n.chart=new window.Van.SliderDashboard(e) 是创建新的仪表盘组件并重绘的代码。
将上面那段代码修改为:
;if(t.dataSet.length<2){Object(Kt.i)(e,n)}else{if(n.chart){n.chart.config.dataSet = t.dataSet;n.chart._calculateCarouselData();if(!n.chart.timeInterval){if(n.chart.carouselData.length<2){n.chart._switchData();}else{n.chart._createInterval();}}}else{(e.timeInterval=n.widget.carousel.autoplaySpeed/1e3,e.container=n.container,n.chart=new window.Van.SliderDashboard(e),Object(Kt.a)(n))}}
注意此处将原来代码开头的英文逗号, 修改为了英文分号; 。
修改部分的逻辑是首先判断n.chart ,如果n.chart 为真,则表示仪表盘组件已经生成过,此时只执行将新的数据传入仪表盘组件。这里n.chart 就是轮播夜光仪表盘绘制出来的组件对象:
n.chart.config.dataSet = t.dataSet; n.chart._calculateCarouselData();
上面两句代码就是将新数据传递给组件,并让组件重新计算轮播要显示的数值。
仪表盘内部切换要显示的维度信息是通过_switchData() 函数进行的,_switchData() 会轮循并绘制显示信息和动画。
但当传入的数据少于2个时,它内部逻辑里就不调用_swichData() 了,导致使将新数据传入仪表盘,并让仪表盘重新计算了要显示的信息,仪表盘也还是显示旧的信息,因此需要判断一下数据长度,如果少于两个,就显式调用_switchData() ,让新信息上显:
if(!n.chart.timeInterval){ if(n.chart.carouselData.length < 2){// 当不存在定时器时才调用switchData n.chart._switchData(); } else {// 若数据维度大于2但没有定时器,则调用_createInterval()创建定时器 n.chart._createInterval(); } }
否则仪表盘的显示的数值信息始终不会变。
用压缩软件打开plugin-com.fr.plugin.wysiwyg.v11-1.3.1.jar ,将修改后的文件preview.622ce744.chunk.js 直接拖入压缩包内相同的目录中,覆盖源文件(可以先备份一下plugin-com.fr.plugin.wysiwyg.v11-1.3.1.jar ,以备出问题后可还原)。
重新打开FineReport,即可看见轮播夜光仪表盘在开启监控刷新 后,不会再在请求后台新数据后,重绘组件,而是在后台静默更新,组件依然按照原来的速度轮播各个维度的信息,如果数据更新了也会显示最新的数据。
当然这种修改是对全局生效的,因此如果想要回原来的效果,只能把代码改回原来的样子。
从修改过程也可以看出,实际上仪表盘组件本身是支持静默更新的,上面修改的代码都是调用组件本来就有的功能,所以我觉得这种数据更新就重绘组件的做法可能是帆软某个产品经理的想法?虽然说需要重绘组件的场景不能说完全没有,但个人觉得大部分业务场景下,静默更新是比较适用的,FVS里也有组件即使开启监控刷新也不会在请求新数据后重绘组件这么突兀。
|