请上传宽度大于 1200px,高度大于 164px 的封面图片
    调整图片尺寸与位置
    滚轮可以放大缩小图片尺寸,按住图片拖动可调整位置,多余的会自动被裁剪掉
取消
yzmkJ4zF3473074(uid:1798935)
职业资格认证:尚未取得认证
FVS, 使用Echarts展示更多种类图表(热力图)
标题: 并解决开启FVS数据更新推送功能下嵌入Echarts图表后无法一起更新的问题.  前言: 此贴参考了论坛中的帖子: fineReport整合echarts制作桑基图-我的帆软 (fanruan.com);    并将其和FVS结合, 解决了数据更新同步的问题.项目背景:  有车间的工单转出需要绘制热力图, 但整体看板是使用FVS制作的, 所以如何在FVS中嵌入Echarts复杂图标就是个问题了 FVS表格自带的Echarts引入, 仅支持简单的 key->value 形式数据的解析, 而不支持像热力图这样的 x,y,value 的复杂数据类型的数据自解析 思路 图表如何绘制?  使用js进行页面元素的插入和数据处理, 渲染操作. 但这时有一个问题, FVS的表格是没有初始化JS的(或许我不知道), 所以我们这里需要在决策报表里面绘制, 然后通过FVS网页框将决策报表引入到FVS大屏.  数据如何获取,更新? 特别是在FVS有数据联动的情况下, 比如我的工单的转出数据是按照天, 周, 月, 年的时间段进行抽取出来的数据, 那我在FVS中更改了筛选条件后, 如何让决策报表里面的热力图数据也同步更新?  FVS有推送更新, 决策报表如何一样即时更新?  如果是用网页框的监控刷新选项, 1. 网页框会整体刷新, 白屏然后展示, 观感上不好. 2. 测试出网页框的监控刷新和FVS的数据推送刷新互斥, 实际上无法使用, 决策报表的初始化JS倒是不互斥, 但是依然有1. 的问题, 太难看.  既然用了JS, 那么干脆用JS的  setInterval  方法算了, 按指定时间轮训重复从数据集获取数据.(注意, 这里不去查SQL, 所以影响的只是网页端的性能. 可以看后续代码部分.). 最后效果:  前期准备 导入 Echarts.js 文件.  下载Echarts: 在此页面 快速上手 - 使用手册 - Apache ECharts  按照说明下载 echarts.js文件.  下面这个链接是截止2024.0913时间的最新Echart.js链接: cdn.jsdelivr.net/npm/echarts@5.5.1/dist/echarts.min.js 导入到FineReport:  将下载好的js文件, 放置在 FineReport服务器 的 webroot 文件夹中, 和WEB_INF同级(注意,这里我测试放到WEB_INF里面引入的时候获取不到, 可能是权限问题, 感兴趣的可以自测下. ) 引入到FineReport:  创建数据集 这里需要注意的是, 这里的变量是要加到全局参数里面, 后面会有用, 切记! FVS设置 网页框组件, 设置参数:  注意, 参数名称一定要和决策报表中的全局参数名称一样.  参数内容一定是绑定了参数的全局参数, 这样设置后, FVS页面通过下拉框/选择按钮修改了数据后, 因为绑定了全局参数, 所以全局参数进行了变化, 这个变化会同步到网页框关联的决策报表的全局参数中, 而网页框的全局参数变化, 会使得数据集的结果变化. 而JS中在循环中通过Value获取的数据也会发生变化.  编写JS代码.  插入标签控件: , 控件名称自定义:  添加初始化后事件:  添加JS:  初始化变量:  这里主要是获取指定sql查询出的数据集.  不使用SQL函数, 所以不影响数据库性能.    var cs0 = "VALUE('查询指定厂的全部车间',1)" var cs1 = "VALUE('查询指定时间段的转出数据',1)" var cs2 = "VALUE('查询指定时间段的转出数据',2)" var cs3 = "VALUE('查询指定时间段的转出数据',3)" 初始化Echarts组件 清空Label控件内容, 并在Label控件中添加div标签: 注意, LABEL0是FR中label的控件名称. 第二句的id名称需要和第三局getElementById的值相同! $("div").empty(); // 往标签控件里添加div,指定id $("div").append(" "); var myChart = echarts.init(document.getElementById("echa"));  数据处理: 用js将数据集数据转换为Echarts所需数据. 按照Echarts不同图标自己处理即可.   // 获取车间数据, 以及所需的三列值 var dept = FR.remoteEvaluate(cs0); var d1 = FR.remoteEvaluate(cs1); var d2 = FR.remoteEvaluate(cs2); var d3 = FR.remoteEvaluate(cs3); // 定义所需值的数组容器 var data = ; // 通过三列查询数据拼接中间数据(转出车间-转入车间-数量) var rawData = ; // 热力图的展示最大值, 默认10 var maxCount = 10; // 如果有比10更大的, 就使用最大值 // 获取rawData for (i = 0; i < d1.length; i++) { counti = d3; if (maxCount < counti) { maxCount = counti; } rawData.push(, d2, counti]); } // 将rawData转换为(x, y, value) rawData.forEach(function(item) { // 找到每个部门在 dept 数组中的索引位置作为 y 轴坐标 var indexx = dept.indexOf(item.toString()); var indexy = dept.indexOf(item.toString()); if (indexx !== -1 && indexy !== -1) { data.push(]); } }); Echarts配置: 注意, 我这里的字体都调的是白色的, 需要自己调整即可.  // 以下为echarts正常配置 var option = { title: { text: '转出数据热力图', left: 'center', top: 20, textStyle: { // 设置字体颜色为白色 color: '#fff' } }, tooltip: { position: 'top' }, grid: { height: '85%', top: '5%' }, xAxis: { type: 'category', // 这里是转换出的数组 data: dept, splitArea: { show: false } }, yAxis: { type: 'category', // 这里是转换出的数组 data: dept, splitArea: { show: false } }, visualMap: { min: 0, max: maxCount, calculable: true, orient: 'vertical', right: '10px', // 将visualMap放置在图表的右侧 top: 'center', // 确保垂直居中 bottom: '0%', textStyle: { // 设置字体颜色为白色 color: '#fff' } }, series: [{ name: '测试图表', type: 'heatmap', // 这里是转换出的数组 data: data, label: { show: true, // 显示标签 position: 'inside', // 标签位置,默认为 'inside' formatter: function(params) { // 自定义标签内容 return params.value; } }, emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0.5)' } } }] }; 整体JS:   要把整个数据处理-解析在setInterval之前重复一遍, 因为setInterval不会开始即运行, 而是指定时间后运行(如这里设置的5s).  setInterval设置的是5s, 自行调整. var cs0 = "VALUE('查询指定厂的全部车间',1)" var cs1 = "VALUE('查询指定时间段的转出数据',1)" var cs2 = "VALUE('查询指定时间段的转出数据',2)" var cs3 = "VALUE('查询指定时间段的转出数据',3)" // 先初始化一次 // 清空标签控件里的内容 $("div").empty(); // 往标签控件里添加div,指定id $("div").append(" "); var myChart = echarts.init(document.getElementById("echa")); // 获取车间数据, 以及所需的三列值 var dept = FR.remoteEvaluate(cs0); var d1 = FR.remoteEvaluate(cs1); var d2 = FR.remoteEvaluate(cs2); var d3 = FR.remoteEvaluate(cs3); // 定义所需值的数组容器 var data = ; // 通过三列查询数据拼接中间数据(转出车间-转入车间-数量) var rawData = ; // 热力图的展示最大值, 默认10 var maxCount = 10; // 如果有比10更大的, 就使用最大值 // 获取rawData for (i = 0; i < d1.length; i++) { counti = d3; if (maxCount < counti) { maxCount = counti; } rawData.push(, d2, counti]); } // 将rawData转换为(x, y, value) rawData.forEach(function(item) { // 找到每个部门在 dept 数组中的索引位置作为 y 轴坐标 var indexx = dept.indexOf(item.toString()); var indexy = dept.indexOf(item.toString()); if (indexx !== -1 && indexy !== -1) { data.push(]); } }); // 以下为echarts正常配置 var option = { title: { text: '转出数据热力图', left: 'center', top: 20, textStyle: { // 设置字体颜色为白色 color: '#fff' } }, tooltip: { position: 'top' }, grid: { height: '85%', top: '5%' }, xAxis: { type: 'category', data: dept, splitArea: { show: false } }, yAxis: { type: 'category', data: dept, splitArea: { show: false } }, visualMap: { min: 0, max: maxCount, calculable: true, orient: 'vertical', right: '10px', // 将visualMap放置在图表的右侧 top: 'center', // 确保垂直居中 bottom: '0%', textStyle: { // 设置字体颜色为白色 color: '#fff' } }, series: [{ name: '测试图表', type: 'heatmap', data: data, label: { show: true, // 显示标签 position: 'inside', // 标签位置,默认为 'inside' formatter: function(params) { // 自定义标签内容 return params.value; } }, emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0.5)' } } }] }; // 设置图表选项 if (option && typeof option === "object") { myChart.setOption(option, true); } setInterval(function() { // 清空标签控件里的内容 // $("div").empty(); // 往标签控件里添加div,指定id // $("div").append(" "); // var myChart = echarts.init(document.getElementById("echa")); // 获取车间数据, 以及所需的三列值 var dept = FR.remoteEvaluate(cs0); var d1 = FR.remoteEvaluate(cs1); var d2 = FR.remoteEvaluate(cs2); var d3 = FR.remoteEvaluate(cs3); // 定义所需值的数组容器 var data = ; // 通过三列查询拼接中间数据(转出车间-转入车间-数量) var rawData = ; // 热力图的展示最大值, 默认10 var maxCount = 10; // 如果有比10更大的, 就使用最大值 // 获取rawData for (i = 0; i < d1.length; i++) { counti = d3; if (maxCount < counti) { maxCount = counti; } rawData.push(, d2, counti]); } // 将rawData转换为(x, y, value) rawData.forEach(function(item) { // 找到每个部门在 dept 数组中的索引位置作为 y 轴坐标 var indexx = dept.indexOf(item.toString()); var indexy = dept.indexOf(item.toString()); if (indexx !== -1 && indexy !== -1) { data.push(]); } }); // 以下为echarts正常配置 var option = { title: { text: '转出数据热力图', left: 'center', top: 20, textStyle: { // 设置字体颜色为白色 color: '#fff' } }, tooltip: { position: 'top' }, grid: { height: '85%', top: '5%' }, xAxis: { type: 'category', data: dept, splitArea: { show: false } }, yAxis: { type: 'category', data: dept, splitArea: { show: false } }, visualMap: { min: 0, max: maxCount, calculable: true, orient: 'vertical', right: '10px', // 将visualMap放置在图表的右侧 top: 'center', // 确保垂直居中 bottom: '0%', textStyle: { // 设置字体颜色为白色 color: '#fff' } }, series: [{ name: '测试图表', type: 'heatmap', data: data, label: { show: true, // 显示标签 position: 'inside', // 标签位置,默认为 'inside' formatter: function(params) { // 自定义标签内容 return params.value; } }, emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0.5)' } } }] }; // 设置图表选项 if (option && typeof option === "object") { myChart.setOption(option, true); } }, 5000);  
FVS页面备注, 评论功能的实现(编辑后入库)
1. 前情     最近给领导做了个财务的月看板, 领导提出了个需求, 每个月的数据构成都不同, 他需要在页面上详细描述内容, 需要可以一个留言的功能.    2. 措施     使用文本框的编辑后事件, 利用js调用SQL函数, insert文本框的内容 3. 提要     使用的数据库: MYSQL8.0.24     SQL函数需要SQL语句执行的返回结果集, 所以必须使用存储过程, 在insert后返回一条结果! 4. 实施  在数据库中创建存储过程:  CREATE DEFINER=`root`@`%` PROCEDURE `ann1`(IN t VARCHAR(50)) BEGIN INSERT INTO common (annotation1) VALUES (t); SELECT 1; END 在文本框控件的编辑事件js中, 添加如下代码:  // 获取文本框控件编辑后的值 var value = this.getValue(); // 拼接sql, value需要拿引号引起来, 避免字符串格式无法存储 var sql = "call ann1('" + value + "')"; // 使用SQL函数 var result = FR.remoteEvaluate('SQL("ITSM测试可写","' + sql + '",1,1)'); 在文本框默认值中, 读取数据库值
FVS自定义分页组件分享
如题, FVS自带的分页太丑了, 而且没法修改, 自己写了一个分页的组件, 分享给大家. 组件功能:  展示总条数, 选择(输入)每页条数, 展示总页数. 按页跳转, 最前/最后跳转, 输入页数跳转功能. 分页组件使用的都是按钮/输入框组件, 大小, 颜色, 方圆, 模糊度, 背景, 选中特效都可自行调整 效果如下: 2024.05.16  更新引入组件后需要对模板做的更改操作 Template1.zip (8.42 K) 前言: 分页使用的是sql中的 limit, 当数据量较大时, 会对性能有较高要求, 查询时间也会随之增加, 慎用! 组件集中有影响性能的组件, 如需要极致的性能, 可以将以下部分删除:       展示总页数的:  TOTALPAGE 组件, 是根据每页条数变动来调用SQL计算总页数的.       模板页面加载结束事件JS: 该JS是将文本框的字体调整至居中, 为了避免换页后失效, 所以一直在循环修改. 如果页面为单页, 或不需要居中显示, 则可以取消此部分 正文:除了引入demo中的分页组件外, 还需要模板自身更改: 1. 模板参数:     - PAGE_SIZE: 每页条数      - THIS_PAGE: 当前页数     - PAGE_STRT: 起始条数   2. 模板数据集   -- 总条数数据集    -- 分页查询数据集   3. 模板页面加载结束事件   "use document"; setInterval(function() { $(".bi-input.display-block,overflow-dot").css({"text-align":"center"}); },100)   4. 修改组件:      总条数:     TOTALPAGE:  即可正常使用.   
Debain下帆软Report(Tomcat)随机自启动解决措施
注: 测试环境为debain10/11. 使用tomcat的程序理论都可使用此方法(如: BI等).  官方文档未给出debain环境下的解决措施, 参考文档会报错, 所以在试错后有了这篇文档.  1. 创建rc.local文件 在/etc下创建rc.local:     touch rc.local 2. 添加如下代码:  #!/bin/sh -e export JAVA_HOME=/你的jdk路径(如: /home/local/jdk1.8.0_91) /你的tomcat的startup.sh的路径(如: /home/local/tomcat/bin/startup.sh) 3. 向rc.local添加权限 chmod +x /etc/rc.local 4. 启动 rc-local systemctl enable --now rc-local 无视警告即可 5. 查看状态 systemctl status rc-local.service 显示绿色,  Active: active 即为正常, 设置成功. 
个人成就
内容被浏览4,492
加入社区1年348天
返回顶部