JS实现LED数字样式

楼主
我是社区第485122位番薯,欢迎点我头像关注我哦~
1. 概述
1.1 预期效果

本文将介绍如何实现 LED 数字样式,效果如下图所示:

单个固定单元格 LED 数字样式:先生成默认 LED 数字样式,用户填报 LED 属性值,点击按钮后,可以自定义 LED 数字效果。

扩展单元格 LED 数字样式:LED 数字样式可以跟随单元格扩展。

1.2 实现思路

通过 JS 加载起始和结束事件实现 LED 样式,通过按钮点击事件获取单元格填报值改变数字效果。

注:本功能不支持导出。

2. 示例
2.1 数据准备

新建普通报表,新建数据集 ds1,数据库查询语句为:SELECT * FROM F财务指标分析

2.2 表格设计

如下图设计表格,需要注意的是 C2~C9 和 B10 单元格需要添加控件。

2.3 添加 JS 事件
2.3.1 生成 LED 样式

设计器菜单栏选择模板>模板Web属性,如下图步骤添加一个加载起始事件。

JS 代码如下:

  1. /*
  2. * selector:需要生成led样式容器的选择器;例  #testId
  3. * color:led灯的颜色;例 red
  4. * width:led灯的宽度;例 100
  5. * height:led灯的高度;例 200
  6. * values:led需要显示的值;例 -123.4
  7. * lineWidth:led灯的线宽;例 5
  8. * italics:倾斜角度;例 10
  9. */


  10. window.ledSetValue= function(selector,color,width,height,values,lineWidth,italics,opacity_){
  11.                 color = color == null || color == ""?"orange":color;
  12.                 width = width == null || width == ""?50:width;
  13.                 height = height == null || height == ""?100:height;
  14.                 values = values == null || values == ""?0:values;
  15.                 lineWidth = lineWidth == null || lineWidth == ""?5:lineWidth;
  16.                 italics = italics == null || italics == ""?0:italics;
  17.          

  18.                 var valuesArr = values.toString().split("");
  19.                 var commaCount = values.toString().match(/\./g) == null?0:values.toString().match(/\./g).length;
  20.                 var divWidth = (valuesArr.length - commaCount) * width + (valuesArr.length - commaCount-1)*lineWidth*0.5 + (width*0.5 - 0.5*lineWidth)*commaCount;
  21.                 //生成一个随机数,该数用来作为canvas画板的id
  22.                 var random = 'canvas' + new Date().getTime().toString() + (Math.random() * 10000000).toString().substring(0, 6).replace(/\./g, '');
  23.                 var html = '<canvas id="'+random +'" width="'+divWidth+'" height="'+height+'" style="transform:skewX('+italics+'deg)">21</canvas>';

  24.                 document.querySelector(selector).innerHTML = html;
  25.                 var c=document.querySelector("#"+random);

  26.                 var ctx=c.getContext("2d");
  27.                 ctx.lineWidth=lineWidth;
  28.                 ctx.strokeStyle = color;

  29.                 var distanceLeft = 0;
  30.                 for(var i=0;i<valuesArr.length;i++){
  31.                         var styleLed = setNumber(valuesArr);

  32.                         if(valuesArr != "."){
  33.                                 ctx.lineCap="round";
  34.                                 //七段数码管第一段(关于七段数码管详情请百度)
  35.                                 ctx.beginPath();
  36.                                 ctx.globalAlpha = styleLed[0];
  37.                                 ctx.moveTo(1.5*lineWidth + distanceLeft,0.5*lineWidth);
  38.                                 ctx.lineTo(width - 1.5*lineWidth + distanceLeft,0.5*lineWidth);
  39.                                 ctx.stroke();
  40.                                 //七段数码管第二段
  41.                                 ctx.beginPath();
  42.                                 ctx.globalAlpha = styleLed[1];
  43.                                 ctx.moveTo(width - 0.5*lineWidth + distanceLeft,1.5*lineWidth);
  44.                                 ctx.lineTo(width - 0.5*lineWidth + distanceLeft,height/2 - lineWidth);
  45.                                 ctx.stroke();
  46.                                 //七段数码管第三段
  47.                                 ctx.beginPath();
  48.                                 ctx.globalAlpha = styleLed[2];
  49.                                 ctx.moveTo(width - 0.5*lineWidth + distanceLeft,height/2 + lineWidth);
  50.                                 ctx.lineTo(width - 0.5*lineWidth + distanceLeft,height  - 1.5*lineWidth);
  51.                                 ctx.stroke();
  52.                                 //七段数码管第四段
  53.                                 ctx.beginPath();
  54.                                 ctx.globalAlpha = styleLed[3];
  55.                                 ctx.moveTo(1.5*lineWidth + distanceLeft,height  - 0.5*lineWidth);
  56.                                 ctx.lineTo(width - 1.5*lineWidth + distanceLeft,height  - 0.5*lineWidth);
  57.                                 ctx.stroke();
  58.                                 //七段数码管第五段
  59.                                 ctx.beginPath();
  60.                                 ctx.globalAlpha = styleLed[4];
  61.                                 ctx.moveTo(0.5*lineWidth + distanceLeft,height/2 + lineWidth);
  62.                                 ctx.lineTo(0.5*lineWidth + distanceLeft,height  - 1.5*lineWidth);
  63.                                 ctx.stroke();
  64.                                 //七段数码管第六段
  65.                                 ctx.beginPath();
  66.                                 ctx.globalAlpha = styleLed[5];
  67.                                 ctx.moveTo(0.5*lineWidth + distanceLeft,1.5*lineWidth);
  68.                                 ctx.lineTo(0.5*lineWidth + distanceLeft,height/2 - lineWidth);
  69.                                 ctx.stroke();
  70.                                 //七段数码管第七段
  71.                                 ctx.beginPath();
  72.                                 ctx.globalAlpha = styleLed[6];
  73.                                 ctx.moveTo(1.5*lineWidth + distanceLeft,height/2);
  74.                                 ctx.lineTo(width - 1.5*lineWidth + distanceLeft,height/2);
  75.                                 ctx.stroke();

  76.                                 distanceLeft += width + 0.5*lineWidth;
  77.                         }else{
  78.                                 ctx.beginPath();
  79.                                 ctx.lineCap="square";
  80.                                 ctx.globalAlpha = 1;
  81.                                 ctx.moveTo(0.25*width - 0.5*lineWidth + distanceLeft,height - lineWidth);
  82.                                 ctx.lineTo(0.25*width - 0.5*lineWidth  + distanceLeft,height - lineWidth);
  83.                                 ctx.stroke();
  84.                                 distanceLeft += 0.5*width - 0.5*lineWidth;
  85.                         }
  86.                 }
  87.                 /*
  88.                  *设置单个数字的值的方法
  89.                  *number:传入单个数字的值
  90.                  *opacity:设置led不亮部分的透明度  
  91.                  */
  92.                 function setNumber(number,opacity=opacity_ ){
  93.                         var styleLed = [];
  94.                         switch(number.toString()) {
  95.                                 case '0':
  96.                                         styleLed = [1,1,1,1,1,1,opacity];
  97.                                         break;
  98.                                 case '1':
  99.                                         styleLed = [opacity,1,1,opacity,opacity,opacity,opacity];
  100.                                         break;
  101.                                 case '2':
  102.                                         styleLed = [1,1,opacity,1,1,opacity,1];
  103.                                         break;
  104.                                 case '3':
  105.                                         styleLed = [1,1,1,1,opacity,opacity,1];
  106.                                         break;
  107.                                 case '4':
  108.                                         styleLed = [opacity,1,1,opacity,opacity,1,1];
  109.                                         break;
  110.                                 case '5':
  111.                                         styleLed = [1,opacity,1,1,opacity,1,1];
  112.                                         break;
  113.                                 case '6':
  114.                                         styleLed = [1,opacity,1,1,1,1,1];
  115.                                         break;
  116.                                 case '7':
  117.                                         styleLed = [1,1,1,opacity,opacity,opacity,opacity];
  118.                                         break;
  119.                                 case '8':
  120.                                         styleLed = [1,1,1,1,1,1,1];
  121.                                         break;
  122.                                 case '9':
  123.                                         styleLed = [1,1,1,1,opacity,1,1];
  124.                                         break;
  125.                                 case '-':
  126.                                         styleLed = [opacity,opacity,opacity,opacity,opacity,opacity,1];
  127.                                         break;
  128.                                 default:
  129.                                         styleLed = [opacity,opacity,opacity,opacity,opacity,opacity,opacity];
  130.                                         break;
  131.                         }
  132.                         return styleLed;
  133.                 }

  134.         }
复制代码
2.3.2 单个固定单元格

1)设计器菜单栏选择模板>模板Web属性,如下图步骤添加一个加载结束事件,调用上面生成 LED 样式的代码,作用对象为单个固定单元格,生成默认 LED 样式。

JS代码如下:

  1. window.ledSetValue("#B11-0-0" ,'red',20,30,-0.032,3,1,0.06);
复制代码

注:在设置冻结和重复列的情况下,td 标签的 id 属性后面几个字符串会一直变动。这个时候元素选择需要改动,把 "#D11-0-0" 改成 "td[id^=D11]"

其中#B11-0-0是 LED 显示位置所在单元格的元素,获取方法如下图所示:

2)如下图步骤给 B10 单元格的按钮添加点击事件,用于获取填报值,进而自定义 LED 样式。

JS 代码如下:

  1. var cell = contentPane.curLGP.getTDCell(0, 0);
  2. contentPane.curLGP.selectTDCell(cell);
  3. var x_ = 'C';
  4. var yanse = contentPane.curLGP.getCellValue(x_ + (a - 8));
  5. var kuandu = contentPane.curLGP.getCellValue(x_ + (a - 7));
  6. var gaodu = contentPane.curLGP.getCellValue(x_ + (a - 6));
  7. var qingxiedu = contentPane.curLGP.getCellValue(x_ + (a - 5));
  8. var toumingdu = contentPane.curLGP.getCellValue(x_ + (a - 4));
  9. var cuxi = contentPane.curLGP.getCellValue(x_ + (a - 3));
  10. var zhi = contentPane.curLGP.getCellValue(x_ + (a - 2));
  11. var danyuange = contentPane.curLGP.getCellValue(x_ + (a - 1));

  12. window.ledSetValue("#" + danyuange + "-0-0", yanse, kuandu, gaodu, zhi, cuxi, qingxiedu, toumingdu);
复制代码

2.3.3 扩展单元格

设计器菜单栏选择模板>模板Web属性,如下图步骤添加一个加载结束事件,调用上面生成 LED 样式的代码,作用对象为扩展单元格,生成指定的 LED 样式。

JS 代码如下:

  1. var x_ = 'C'; //设置具体哪列展示成LED样式 ,该列的值必须是数字
  2. var num_ = 16; //具体从哪一行开始展示

  3. $('td[id^="' + x_ + '"]').each(function() {
  4.         var num = $(this).attr('id').substring(1, $(this).attr('id').indexOf('-'));

  5.         if (parseInt(num) < num_) {
  6.                 return true;
  7.         }

  8.         var id = $(this).attr('id').substring(0, $(this).attr('id').indexOf('-'));
  9.         var qingxiedu = contentPane.curLGP.getCellValue(id);
  10.         if (qingxiedu.length == 0 || typeof qingxiedu == 'undefined') {
  11.                 qingxiedu = '0';
  12.         }

  13.         window.ledSetValue("#" + $(this).attr('id'), 'red', 20, 30, qingxiedu, 3, 1, 0.06);
  14. })
复制代码

2.4 效果预览

保存报表,点击填报预览,效果如 1.1预期效果 所示。

注:不支持移动端。

3. 模板下载

已完成的模板,可参见:%FR_HOME%\webapps\webroot\WEB-INF\reportlets\doc\JS\填报预览JS实例\LED式数字实现模板.cpt

点击下载模板:LED式数字实现模板.cpt



编辑于 2020-12-8 15:52  
编辑于 2020-12-8 15:53  
分享扩散:

沙发
发表于 2021-4-6 16:44:10
板凳
发表于 2022-9-16 16:57:01
思路很好 样式难看额
地板
发表于 2022-9-27 14:34:21
66666666
5楼
发表于 2022-11-15 15:12:10

这两处的valuesArr应该改为valuesArr[i]

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

4回帖数 6关注人数 8927浏览人数
最后回复于:2022-11-15 15:16

返回顶部 返回列表