# Ciyon 数据大屏开发指南 ## 技术架构 ### 技术栈 - **前端框架**:ciybigscreen.js(自定义大屏面板框架) - **数据可视化**:ECharts - **3D地图**:Cesium - **后端语言**:PHP(命名空间结构) - **辅助库**:ciy.js(通用工具库) ### 目录结构 ``` web/admin/demo/bs/ ├── index.html # 大屏入口页面 ├── index.php # 后端数据接口 └── b64/ # 图表组件JS文件 ├── bank1_c1.js # 银行大屏-中心上部数字卡片 ├── bank1_c2.js # 银行大屏-中心地图 ├── bank1_l1.js # 银行大屏-左侧饼图 ├── farm1_bg_cemap.js # 农场大屏-3D地图背景 └── ... # 其他组件 ``` --- ## 核心开发模式 ### bigpanel 面板系统 **核心对象**:`ciyclass.bigpanel` ```javascript // 创建面板 var chtpls = {}; chtpls['bank1'] = new ciyclass.bigpanel({ name: 'panel_bank1', // 面板唯一标识 jspath: './b64/', // 组件JS文件路径 style: 'position:absolute;top:4em;left:5px;right:5px;bottom:20px;', animation: 'ani1', // 动画效果 mask: '' // 遮罩层颜色 }); ``` **关键方法**: | 方法 | 说明 | 示例 | |------|------|------| | `addplot(opn)` | 添加图表组件 | `addplot({jsname: 'bank1_c1', style: '...'})` | | `run(fsec)` | 启动数据轮询 | `run({'bank_c1': 50})` // 50秒刷新一次 | | `setbtns(opn)` | 设置关闭按钮 | `setbtns({template: 'close1'})` | | `resize()` | 窗口大小改变时调用 | 自动调用所有组件的resize方法 | | `distory()` | 销毁面板 | 清理所有组件和定时器 | --- ### 图表组件开发规范 每个图表组件是一个独立的JS文件,必须遵循以下规范: **文件命名**:`{面板名}_{位置标识}.js` - 位置标识:`c1`(中上)、`c2`(中)、`l1`(左上)、`l2`(左中)、`l3`(左下)、`r1`(右上)、`r2`(右中)、`r3`(右下) **基本结构**: ```javascript function ciy_chart_bank1_c1(opdata) { var thos = this; // 必须定义:指定需要调用的后端接口 this.func = ['bank_c1']; // 组件变量 this.lastdata = {}; var chart1 = null; // ECharts实例 // 必须实现:数据设置方法 this.setdata = function (funame, data) { if (!data) return; this.lastdata[funame] = data; // 更新DOM元素 $5('[data-num="n1"]', opdata.container).text(data.n1); // 或更新ECharts图表 chart1.setOption({...}); } // 必须实现:响应窗口大小变化 this.resize = function () { if (chart1) chart1.resize(); } // 必须实现:清理资源 this.distory = function () { if (chart1) chart1.dispose(); clearInterval(timer); } // 组件初始化:添加DOM结构 opdata.container.append(`
`); // 初始化ECharts chart1 = echarts.init($5('#chart1', opdata.container)[0], 'dark'); chart1.setOption(option); } ``` **关键属性**: | 属性 | 说明 | 示例 | |------|------|------| | `this.func` | 需要调用的后端接口数组 | `['bank_c1', 'bank_c2']` | | `this.prefunc` | 接口前缀(可选) | `'farm_'` | | `opdata.container` | 组件容器DOM | 用于添加子元素 | --- ### 后端接口开发规范 **PHP类结构**: ```php $i, 'name' => '风控' . $i, 'value' => rand(100, 300) ); } return succjson($ret); } } ``` **命名规范**: - 方法名:`json_{面板名}_{图表名}` - 返回格式:使用 `succjson($ret)` 统一返回JSON - 数据结构:简单类型、数组、对象均可 --- ## 数据流机制 ### 轮询机制 ```javascript // 面板启动时设置刷新频率(单位:0.5秒) chtpls['bank1'].run({ 'bank_c1': 50, // 每25秒刷新一次 'bank_c2': 10, // 每5秒刷新一次 'bplant': 50 // 每25秒刷新一次 }); ``` ### 数据请求流程 ``` 1. bigpanel.run() 启动定时器(500ms间隔) 2. 检查每个func的倒计时 3. 倒计时为0时调用 ciyfn.callfunc() 4. 请求后端:POST json_{func} 5. 返回JSON数据 6. 调用对应组件的 setdata(funame, data) 7. 组件更新DOM或图表 8. 重置倒计时 ``` ### 跨组件数据共享 ```javascript // 全局数据对象 var Glob = { post: {}, // 传递给后端的公共参数 bet: 1, // 屏幕缩放比例 fontsize: 14 // 字体大小 }; // 设置公共参数 ciyfn.callfunc('init', {}, function (json) { Glob.post.orgid = json.orgid; Glob.myparam = { title: json.title }; }); // 组件内使用 // 后端接口会自动合并 Glob.post 和 thos.post ``` --- ## 常用组件类型 ### 数字卡片组件 ```javascript // bank1_c1.js function ciy_chart_bank1_c1(opdata) { this.func = ['bank_c1']; this.setdata = function (funame, data) { $5('[data-num="n1"]', opdata.container).text(data.n1); $5('[data-num="n2"]', opdata.container).text(data.n2); $5('[data-bank]', opdata.container).text(data.name); } opdata.container.append(`
--
贷款金额 (万元)
`); } ``` ### ECharts饼图组件 ```javascript // bank1_l1.js function ciy_chart_bank1_l1(opdata) { this.func = ['bank_l1']; var chart1 = null; this.setdata = function (funame, data) { var option = { series: [{ type: 'pie', radius: ['25%', '40%'], data: data.pie }] }; chart1.setOption(option); } opdata.container.append('
'); chart1 = echarts.init($5('#chart1')[0], 'dark'); // 自动高亮动画 var idx = -1; setInterval(function () { chart1.dispatchAction({ type: 'highlight', dataIndex: idx }); idx = (idx + 1) % data.pie.length; }, 2200); } ``` ### Cesium地图组件 ```javascript // bank1_c2.js function ciy_chart_bank1_c2(opdata) { this.func = ['bank_c2']; var thos = this; var ce = null; this.setdata = function (funame, data) { if (ce) return; // 只初始化一次 ce = new ciyearth(); ce.init({ domid: 'map1', wmts_source: 4, wmts_style: 2 }); // 添加标记点 for (var i in data.bplants) { var marker = ce.addmarker({ lat: data.bplants[i].lat, lng: data.bplants[i].lng, img: '/ud/bill/map' + data.bplants[i].cmcode + '.png' }); marker.ciydata = data.bplants[i]; } // 点击事件 ce.ciyevent = function (type, act, data) { if (type == 'entity' && act == 'leftclick') { showfarm(data.entity.ciydata); } }; } this.distory = function () { if (ce) ce.destroy(); } opdata.container.append('
'); } ``` ### 图片轮播组件 ```javascript function ciy_chart_farm_l3(opdata) { this.func = ['farm_l3']; var thos = this; var cyc = null; this.setdata = function (funame, data) { var imgs = data.farm.picszz.split('~'); cyc = new ciyclass.bigcychange({ values: imgs, cycsec: 5, changecb: function (img) { $5('img', opdata.container).attr('src', img); } }); } this.distory = function () { if (cyc) cyc.distory(); } opdata.container.append(''); } ``` --- ## 高级功能 ### 弹窗面板 ```javascript function showvideo(mas) { var chtname = 'video1'; chtpls[chtname] = new ciyclass.bigpanel({ name: 'panel_' + chtname, jspath: './b64/', animation: 'small', style: 'position:absolute;top:50px;left:50px;right:50px;bottom:50px;z-index:2010;' }); chtpls[chtname].post = { videoid: mas.id, img: mas.capture }; chtpls[chtname].addplot({ jsname: chtname + '_c1', style: 'position:absolute;left:1em;right:1em;bottom:1em;top:5em;' }); chtpls[chtname].setbtns({ template: 'close1', hideopacity: 0.8 }); chtpls[chtname].run({}); } ``` ### 地图弹窗提示 ```javascript this.showpopup = function (html, pos) { if (thos.popup) thos.popup.remove(); var oset = $5(opdata.container).offset(); thos.popup = $5(''); thos.popup.css({ top: pos.y - oset.top, left: pos.x - oset.left, opacity: 1 }); opdata.container.append(thos.popup); } ``` ### 屏幕自适应 ```javascript // 设置基准分辨率 ciyfn.big_resolution(1536, 864); ciyfn.big_setbetsize(1536); // 响应窗口大小变化 window.addEventListener("resize", function () { ciyfn.big_setbetsize(1536); for (var ipl in chtpls) { chtpls[ipl].resize(); } }); ``` --- ## 开发最佳实践 ### 性能优化 1. **减少重复初始化** ```javascript this.setdata = function (funame, data) { if (ce) return; // 地图只初始化一次 // ...初始化代码 } ``` 2. **使用全局缩放比例** ```javascript var option = { fontSize: 18 * Glob.bet, // 根据屏幕缩放 borderRadius: 4 * Glob.bet }; ``` 3. **及时清理定时器** ```javascript this.distory = function () { clearInterval(t_autohight); if (chart1) chart1.dispose(); } ``` ### 样式规范 ```css /* 渐变文字 */ background: linear-gradient(to bottom, #ffffff, #50c4eb 60%); background-clip: text; -webkit-background-clip: text; color: transparent; /* 动画 */ @keyframes opa { 0% { opacity: 1; } 10% { opacity: 0.5; } 20% { opacity: 1; } } /* 弹窗样式 */ .popup-box { position: absolute; z-index: 999; transform: translateX(-50%) translateY(-100%); pointer-events: none; transition: all 0.5s; } ``` ### 调试技巧 ```javascript // 开发模式 if (urlp.dev) { console.log('组件名称', data); // ...调试代码 } // 查看当前刷新频率 console.log(funcsecs); // 查看所有接口的倒计时 // 手动刷新所有组件 setdata(); ``` --- ## 常见问题 ### Q1: 组件不显示数据? **检查**: 1. `this.func` 数组是否正确 2. 后端接口命名是否匹配 `json_{func}` 3. `setdata()` 方法是否正确处理数据 ### Q2: 地图不显示? **检查**: 1. 容器是否有高度:`style="height:100%"` 2. 初始化前是否已添加DOM 3. Cesium资源是否加载:`/zces108/Cesium.js` ### Q3: 窗口调整后图表变形? **解决**: ```javascript window.addEventListener("resize", function () { chtpls[ipl].resize(); // 调用每个面板的resize }); ``` ### Q4: 数据刷新太频繁? **调整**: ```javascript chtpls['bank1'].run({ 'bank_c1': 100 // 增加刷新间隔(单位:0.5秒) }); ``` --- ## 开发流程 ### 新建大屏步骤 1. **创建目录和文件** ``` web/admin/demo/bs/ ├── index.html ├── index.php └── b64/ ``` 2. **编写 index.html** - 引入必要JS库 - 创建 `ciyclass.bigpanel` - 添加图表组件 3. **编写 index.php** - 创建 `json_init()` 接口 - 为每个组件创建数据接口 4. **开发组件JS文件** - 实现 `setdata()`、`resize()`、`distory()` - 添加DOM结构 - 初始化ECharts或其他库 5. **测试调试** - 使用 `urlp.dev` 开发模式 - 检查数据流 - 优化性能 --- ## 参考资源 ### 技术文档 - ECharts: https://echarts.apache.org/ - Cesium: https://cesium.com/ - jQuery: https://jquery.com/ ### 内部资源 - 样式文件:`/jscss/style.css` - 大屏样式:`/ud/bigscreen/bigscr.css` - 图片资源:`/ud/bigscreen/` - 字体资源:`/ud/bigscreen/` ### 示例代码 - 银行大屏:`web/admin/demo/bs/` - 参考组件:`b64/bank1_*.js` --- ## bigscreen CSS 资源详解 ### 目录结构 ``` /web/ud/bigscreen/ ├── bigscr.css # 大屏核心样式文件 ├── bg/ # 背景图片(bg01.png - bg04.png) ├── border/ # 边框图片(34种通用边框 + 4种文本边框) ├── caption/ # 标题样式(11种大标题 + 1种底部样式) ├── cir/ # 圆形装饰 ├── font/ # 字体文件(15种) ├── fontweb/ # Web字体 ├── icon/ # 图标 ├── orn/ # 装饰元素 └── tit/ # 小标题(6种) ``` ### 字体资源(15种) #### 中文/装饰字体(7种) | 字体名 | 文件路径 | 用途场景 | 推荐使用 | |--------|----------|----------|----------| | `fnt01` | font/fnt01.ttf | 大屏主标题(cap02, cap06, cap07, cap09, cap10, cap11) | ⭐⭐⭐⭐⭐ | | `fnt02` | font/fnt02.ttf | 中等标题(cap03, cap05) | ⭐⭐⭐⭐ | | `fnt03` | fontweb/fnt03.ttf | 网页特殊字体 | ⭐⭐⭐ | | `fnt04-fnt07` | font/fnt04~07.ttf | 装饰字体备用 | ⭐⭐ | #### 小标题字体(4种) | 字体名 | 文件路径 | 格式 | |--------|----------|------| | `xt01` | font/xt01.ttf | .ttf | | `xt02` | font/xt02.otf | .otf | | `xt03` | font/xt03.otf | .otf | | `xt04` | font/xt04.ttf | .ttf | #### 英文/数字字体(2种) | 字体名 | 文件路径 | 用途 | 推荐使用 | |--------|----------|------|----------| | `eng01` | font/eng01.ttf | 英文/数字1 | ⭐⭐⭐ | | `eng02` | font/eng02.ttf | 英文/数字2(数字卡片常用) | ⭐⭐⭐⭐⭐ | #### 黑体系列(3种) | 字体名 | 文件路径 | 粗细 | |--------|----------|------| | `hs-bold` | font/hs-bold.ttf | 粗体 | | `hs-light` | font/hs-light.ttf | 细体 | | `hs-normal` | font/hs-normal.ttf | 常规 | **使用示例**: ```css /* 大屏标题 */ font-family: fnt01; /* 数字卡片 */ font-family: eng02; font-size: 1.8em; letter-spacing: 4px; /* 复合标题 */ font-family: SimHei, STHeiti, 黑体; ``` ### 背景样式(4种) | 类名 | 背景图片 | 渐变配色 | 适用场景 | |------|----------|----------|----------| | `.bd01` | bg/bg01.png | `radial-gradient(#232f5a, #232f5a)` | 通用深蓝大屏 | | `.bd02` | bg/bg02.png | `radial-gradient(#232f5a, #0b1121)` | 深蓝+黑色渐变 | | `.bd03` | bg/bg03.png | `radial-gradient(#232f5a, #0b1121)` | 备用深色背景 | | `.bd04` | bg/bg04.png | `radial-gradient(#092b46, #041320)` | 现代海蓝色 ⭐ | **共同特性**: - `height: 100vh` - `color: #ffffff` - 背景图片设置为 `repeat` 重复平铺 **使用示例**: ```html ``` ### 边框样式(38种) #### 通用边框(34种) | 类名 | 切割值 | 边框宽度 | 内边距 | 重复模式 | 背景色 | 推荐度 | |------|--------|----------|--------|----------|--------|--------| | `.brimg01` | 15 22 19 16 | 15px 22px 19px 16px | 10px 15px 15px 10px | - | - | ⭐⭐⭐⭐ | | `.brimg02` | 15 21 20 16 | 15px 21px 20px 16px | 10px 15px 15px 10px | - | - | ⭐⭐⭐⭐ | | `.brimg03` | 13 13 13 13 | 13px 13px 13px 13px | 10px 10px | - | `#00000011` | ⭐⭐⭐ | | `.brimg04` | 103 168 103 168 | 103px 168px 103px 168px | 10px 10px | - | - | ⭐⭐ | | `.brimg05` | 97 76 97 76 | 97px 76px 97px 76px | 15px | - | - | ⭐⭐ | | `.brimg10` | 14 | 14px | 8px | - | `#00000011` | ⭐⭐⭐ | | `.brimg21` | 50 28 50 28 | 50px 28px 50px 28px | 3px 8px 3px 8px | - | `transparent` | ⭐⭐⭐ | | `.brimg33` | 315 315 315 315 | 315px 315px 315px 315px | 7px | - | `transparent` | ⭐⭐ | | `.brimg34` | 20 21 20 21 | 20px 21px 20px 21px | 7px | - | `#00000011` | ⭐⭐⭐⭐⭐ | **推荐使用**: - `.brimg34` - 常用边框(地图容器常用)⭐⭐⭐⭐⭐ - `.brimg03` / `.brimg10` / `.brimg19` - 简薄边框(带半透明背景)⭐⭐⭐ - `.brimg21` / `.brimg23` / `.brimg24` / `.brimg25` - 透明边框⭐⭐⭐ #### 文本边框(4种) | 类名 | 切割值 | 边框宽度 | 内边距 | 特色 | |------|--------|----------|--------|------| | `.brtxt01` | 2 23 22 23 | 2px 23px 22px 23px | 3px 10px | 红色警告边框,字体加粗 | | `.brtxt02` | 35 60 35 60 | 35px 60px 35px 60px | 10px 20px | 装饰文本边框1 | | `.brtxt03` | 30 54 30 54 | 30px 54px 30px 54px | 10px 20px | 装饰文本边框2 | | `.brtxt04` | 31 93 31 71 | 31px 93px 31px 71px | 10px 20px | 装饰文本边框3 | **brtxt01 特有样式**: ```css background: #ff000029; color: #cc0000; text-shadow: 1px 1px 0 #000000; font-weight: bold; ``` **使用示例**: ```html
警告信息
``` ### 标题样式(11种大标题 + 1种底部样式) #### 大标题(11种) | 类名 | 高度 | 最小宽度 | 字体 | 渐变色 | 特色 | 推荐度 | |------|------|----------|------|--------|------|--------| | `.cap01` | 100px | 1000px | 默认 | 白→白70%→青 | 倒影效果 | ⭐⭐⭐⭐ | | `.cap02` | 50px | 1200px | fnt01 | 白→浅蓝 | 简洁大标题 | ⭐⭐⭐⭐ | | `.cap03` | 40px | 1000px | fnt02 | 白30%→深蓝 | 紧凑标题 | ⭐⭐⭐ | | `.cap04` | 40px | 1000px | 默认 | 白→浅蓝 | 线条装饰 | ⭐⭐⭐ | | `.cap05` | 40px | 1000px | fnt02 | 白→青色 | 青色渐变 | ⭐⭐⭐ | | `.cap06` | 120px | 1200px | fnt01 | 白→青色 | 大标题带装饰 | ⭐⭐⭐ | | `.cap07` | 80px | 1600px | fnt01 | 白→青色 | 超宽标题 | ⭐⭐⭐ | | `.cap08` | 65px | 900px | SimHei | - | 复合标题(h1+h2) | ⭐⭐⭐⭐ | | `.cap09` | 48px | 1300px | fnt01 | 白→浅蓝60% | 倒影效果 | ⭐⭐⭐⭐⭐ | | `.cap10` | 42px | 950px | fnt01 | 深蓝→白50% | 蓝白渐变 | ⭐⭐⭐⭐ | | `.cap11` | 60px | 1260px | fnt01 | 白→浅蓝50% | 双行标题(h1+h2) | ⭐⭐⭐⭐ | **通用标题样式**: ```css background-clip: text; -webkit-background-clip: text; color: transparent; text-align: center; ``` **倒影效果**(cap01, cap09): ```css -webkit-box-reflect: below -35px -webkit-linear-gradient(transparent, transparent 20%, rgba(0,0,0,0.23)); ``` #### 底部样式(1种) | 类名 | 高度 | 背景 | 对齐 | |------|------|------|------| | `.btm01` | 20px | btm01.png(底部居中) | 居中 | **使用示例**: ```html
数据大屏标题
简洁标题

主标题

副标题

底部文字
``` ### 小标题样式(6种) | 类名 | 高度 | 左边距 | 最小宽度 | 背景图 | |------|------|--------|----------|--------| | `.tit05` | 30px | 50px | 230px | tit/05.png(左上角) | ```css .tit05 { height: 30px; display: inline-block; padding: 4px 0 0 50px; min-width: 230px; background: url(./tit/05.png) top left no-repeat; background-size: contain; } ``` ### 动画效果(1种) #### 立方体展开动画 ```css @keyframes ani01_cube { 0% { transform: scale(0) rotate(0deg) translate(-50%, -50%); opacity: 0.2; } 5% { transform: scale(50) rotate(660deg) translate(-50%, -50%); opacity: 0; } 100% { transform: scale(50) rotate(660deg) translate(-50%, -50%); opacity: 0; } } .ani01 li { position: absolute; top: 50vh; left: 50vw; width: 10px; height: 10px; border: solid 1px #0039ad; color: transparent; transform-origin: top left; transform: scale(0) rotate(0deg) translate(-50%, -50%); animation: ani01_cube 20s ease-in forwards infinite; } ``` **效果**:屏幕中心的边框立方体快速放大旋转消失,形成炫酷的展开效果 ### 全局基础样式 ```css * { user-select: none; /* 禁止文本选择 */ -webkit-user-select: none; } span { vertical-align: middle; /* span垂直居中 */ } img { vertical-align: middle; /* 图片垂直居中 */ } ``` ### 资源速查表 **字体选择**: ```css font-family: fnt01; /* 大屏主标题 ⭐⭐⭐⭐⭐ */ font-family: fnt02; /* 中等标题 ⭐⭐⭐⭐ */ font-family: eng02; /* 数字展示 ⭐⭐⭐⭐⭐ */ font-family: SimHei; /* 复合标题(cap08) ⭐⭐⭐⭐ */ ``` **背景选择**: ```html ``` **边框选择**: ```html
``` **标题选择**: ```html
``` --- ## ciybigscreen.js API 详解 ### 类:`ciyclass.bigpanel` **功能**:大屏面板管理核心类 #### 构造函数参数 | 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | `name` | String | ✓ | - | 面板唯一标识(用于DOM的id) | | `jspath` | String | ✓ | - | 组件JS文件路径(如 `'./b64/'`) | | `style` | String | - | `''` | 面板容器内联样式 | | `prop` | String | - | `''` | 面板容器HTML属性 | | `animation` | String | - | - | 动画类型('ani1', 'ani2', 'small') | | `mask` | String | - | - | 遮罩层颜色(如 `'rgba(0,0,0,0.5)'`) | **使用示例**: ```javascript var chtpls = {}; chtpls['bank1'] = new ciyclass.bigpanel({ name: 'panel_bank1', // 必填 jspath: './b64/', // 必填 style: 'position:absolute;top:4em;left:5px;right:5px;bottom:20px;', animation: 'ani1', mask: 'rgba(0,0,0,0.5)' }); ``` #### 实例属性 | 属性 | 类型 | 说明 | |------|------|------| | `this.container` | jQuery对象 | 面板容器DOM对象 | | `this.post` | Object | 传递给后端的公共参数(每个组件独有) | **使用示例**: ```javascript chtpls['bank1'].post = { bankid: 123, orgid: 1 }; ``` #### 方法详解 **1. `addplot(opn)` - 添加图表组件** **参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `opn.jsname` | String | ✓ | 组件名称(如 `'bank1_c1'`) | | `opn.style` | String | - | 组件容器样式 | | `opn.prop` | String | - | 组件容器HTML属性 | **使用示例**: ```javascript chtpls['bank1'].addplot({ jsname: 'bank1_c1', style: 'position:absolute;left:0;top:0;width:33%;height:33%;', prop: 'data-id="chart1"' }); ``` **内部流程**: ``` 1. 创建组件加载状态:plots[opn.jsname] = { load: 0 } 2. 动态加载JS文件:ciyfn.loadjs('ciy_chart_' + opn.jsname, ...) 3. 加载成功后创建容器:load = 1 4. 添加到面板容器:load = 2 5. 实例化组件类:new window['ciy_chart_' + opn.jsname]() ``` **2. `setbtns(opn)` - 设置按钮** **参数**: | 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | `opn.template` | String | - | - | 模板类型(如 `'close1'`) | | `opn.html` | String | - | `''` | 自定义按钮HTML | | `opn.hideopacity` | Number | - | `0.9` | 隐藏时透明度(0-1) | | `opn.hidesec` | Number | - | `5` | 鼠标静止X秒后隐藏 | | `opn.top` | String | - | `'2px'` | 按钮顶部位置 | | `opn.click` | Function | - | - | 自定义点击事件 | **使用示例**: ```javascript // 使用内置模板 chtpls['bank1'].setbtns({ template: 'close1', hideopacity: 0.9, hidesec: 5, top: '2px' }); // 自定义按钮 chtpls['bank1'].setbtns({ html: '', click: function(e) { console.log('按钮被点击'); } }); ``` **内置模板**: - `close1` - 关闭按钮(右上角×) **自动隐藏机制**: - 监听 `mousemove` 事件更新时间戳 - 每500ms检查是否超过 `hidesec` 秒未操作 - 超时则降低透明度到 `hideopacity` **3. `run(fsec)` - 启动数据轮询** **参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `fsec` | Object | ✓ | 刷新频率配置(键为接口名,值为0.5秒的倍数) | **使用示例**: ```javascript chtpls['bank1'].run({ 'bank_c1': 50, // 每25秒刷新一次(50 × 0.5秒) 'bank_c2': 10, // 每5秒刷新一次(10 × 0.5秒) 'bplant': 50 // 每25秒刷新一次 }); ``` **内部流程**: ``` 初始化阶段(仅执行一次) └─ 遍历所有组件 └─ 读取组件的 this.func 数组 └─ 为每个接口创建 funcsecs 对象 └─ 设置初始倒计时 t=0 和最大间隔 max 轮询阶段(每500ms执行一次) └─ 遍历 funcsecs ├─ t == 0?发起请求 │ ├─ 合并参数:Glob.post + thos.post │ ├─ 调用 ciyfn.callfunc(ifu, post, callback) │ ├─ 成功: │ │ ├─ 重置倒计时:t = max │ │ └─ 分发数据到所有相关组件 │ └─ 失败:t = 5(5秒后重试) └─ t--(倒计时递减) ``` **数据分发逻辑**: ```javascript // 遍历所有组件 for (var iplot in plots) { // 检查组件是否匹配(通过 prefunc) if (plots[iplot].clss.prefunc != funcsecs[ifu].prefunc) continue; // 提取函数名(去掉前缀) var funcstr = ifu.substring(funcsecs[ifu].prefunc.length); // 检查组件是否需要此数据 if (plots[iplot].clss.func.indexOf(funcstr) == -1) continue; // 调用组件的 setdata 方法 if (typeof (plots[iplot].clss.setdata) == 'function') { plots[iplot].clss.setdata(funcstr, jsondata); } } ``` **4. `setdata()` - 手动刷新所有组件** **参数**:无 **功能**:临时方法,用于调试或手动触发刷新 **使用示例**: ```javascript chtpls['bank1'].setdata(); ``` **5. `resize()` - 窗口大小改变响应** **参数**:无 **功能**:遍历所有组件,调用其 `resize()` 方法 **使用示例**: ```javascript window.addEventListener("resize", function () { ciyfn.big_setbetsize(1536); for (var ipl in chtpls) { chtpls[ipl].resize(); } }); ``` **6. `distory()` - 销毁面板** **参数**:无 **功能**:清理面板资源,包括定时器、组件、DOM元素 **清理流程**: ``` 1. 清除定时器:tick, tick_btns 2. 遍历所有组件 └─ 调用组件的 distory() 方法 └─ 删除组件对象 3. 播放关闭动画(如果设置了 animation) 4. 移除DOM元素 ``` **使用示例**: ```javascript chtpls['bank1'].distory(); delete chtpls['bank1']; ``` --- ### 工具函数:`ciyfn.big_setbetsize(basewidth, fontsize)` **功能**:设置大屏缩放比例和字体大小 **参数**: | 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | `basewidth` | Number | ✓ | - | 基准设计宽度(如 1536) | | `fontsize` | Number/String | - | `'auto'` | 字体大小('auto' 或 具体数值) | **返回值**:无 **使用示例**: ```javascript ciyfn.big_setbetsize(1536); // 自动计算 ciyfn.big_setbetsize(1536, 16); // 指定字体大小 ciyfn.big_setbetsize(1536, 0); // 不调整字体 ``` **计算逻辑**: ``` 1. 获取屏幕宽度:window.screen.width 2. 开发模式特殊处理(urlp.dev) └─ devicePixelRatio < 0.8 时放大屏幕宽度 3. 屏幕宽度 > 基准宽度? └─ 是:计算缩放比例 bet = screenwidth / basewidth └─ 是:计算字体 fontsize = 14 * bet 4. 设置全局样式 └─ $5('body').css('fontSize', fontsize) 5. 更新全局变量 └─ Glob.fontsize = fontsize - 2 └─ Glob.bet = bet ``` **使用场景**: ```javascript // 页面加载时 ciyfn.big_resolution(1536, 864); ciyfn.big_setbetsize(1536); // 窗口大小改变时 window.addEventListener("resize", function () { ciyfn.big_setbetsize(1536); for (var ipl in chtpls) { chtpls[ipl].resize(); } }); ``` --- ### 工具函数:`ciyfn.big_resolution(width, height)` **功能**:检查屏幕分辨率是否匹配建议值 **参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `width` | Number | ✓ | 基准宽度 | | `height` | Number | ✓ | 基准高度 | **返回值**:无 **使用示例**: ```javascript ciyfn.big_resolution(1536, 864); ``` **检查流程**: ``` 1. 检查物理分辨率:window.screen.width/height └─ 不匹配?提示:"最佳分辨率为:1536 x 864" 2. 检查窗口宽度:window.innerWidth └─ 不等于基准宽度?返回(判断为调试模式) 3. 检查窗口高度:window.innerHeight └─ 小于基准高度?提示:"请按F11,进入全屏模式" ``` **使用场景**: ```javascript // 页面加载时检查 ciyfn.big_resolution(1536, 864); ``` --- ### 类:`ciyclass.bigcychange` **功能**:值循环切换工具(用于图片轮播、数据切换等) #### 构造函数参数 | 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | `values` | Array | ✓ | - | 值数组 | | `changecb` | Function | ✓ | - | 值改变时的回调函数 | | `cycsec` | Number | - | `5` | 切换间隔(秒) | **使用示例**: ```javascript var cyc = new ciyclass.bigcychange({ values: ['img1.jpg', 'img2.jpg', 'img3.jpg'], cycsec: 5, changecb: function (img) { $5('img', opdata.container).attr('src', img); } }); ``` #### 实例属性 | 属性 | 类型 | 说明 | |------|------|------| | `this.value` | Any | 当前值 | #### 方法详解 **1. `change(mm, longsec)` - 手动切换到指定值** **参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `mm` | Any | ✓ | 要切换到的值 | | `longsec` | Number | - | 停留时长(秒),默认使用 cycsec | **返回值**:Boolean(成功返回 true,失败返回 false) **使用示例**: ```javascript cyc.change('img2.jpg', 10); // 切换到'img2.jpg',停留10秒 cyc.change('img1.jpg'); // 切换到'img1.jpg',使用默认间隔 ``` **2. `distory()` - 销毁定时器** **参数**:无 **返回值**:无 **使用示例**: ```javascript cyc.distory(); ``` **完整使用示例**: ```javascript function ciy_chart_farm_l3(opdata) { this.func = ['farm_l3']; var thos = this; var cyc = null; this.setdata = function (funame, data) { var imgs = data.farm.picszz.split('~'); cyc = new ciyclass.bigcychange({ values: imgs, cycsec: 5, changecb: function (img) { $5('img', opdata.container).attr('src', img); } }); } this.distory = function () { if (cyc) cyc.distory(); } opdata.container.append(''); } ``` --- ### 全局变量:`Glob` | 属性 | 类型 | 说明 | |------|------|------| | `Glob.post` | Object | 传递给后端的公共参数(所有面板共享) | | `Glob.bet` | Number | 屏幕缩放比例 | | `Glob.fontsize` | Number | 字体大小 | | `Glob.myparam` | Object | 自定义参数 | **使用示例**: ```javascript // 页面加载时设置公共参数 ciyfn.callfunc('init', {}, function (json) { Glob.post.orgid = json.orgid; Glob.myparam = { title: json.title }; }); // 组件内使用 var option = { fontSize: 18 * Glob.bet, borderRadius: 4 * Glob.bet }; ``` --- ## 样式命名规范与最佳实践 ### CSS命名规范 为避免样式冲突,组件内部CSS应遵循以下规范: #### BEM命名法 ```css /* 面板_组件__元素 */ .bank1-c1__num { } .bank1-c1__title { } .farm1-l2__info { } .farm1-l2__item { } ``` **示例**: ```javascript opdata.container.append(`
--
贷款金额
`); // 动态注入样式 var style = document.createElement("style"); style.innerHTML = ` .bank1-c1__num { font-size: 1.8em; font-weight: bold; color: #ffffff; } .bank1-c1__title { font-size: 0.8em; color: #6dcdee; } `; window.document.head.appendChild(style); ``` #### ID选择器(配合 opdata.container) ```javascript // 添加元素时指定ID opdata.container.append('
'); // 访问时限定在容器内 var chart1 = echarts.init($5('#chart1', opdata.container)[0], 'dark'); ``` #### data-* 属性选择器 ```javascript // 添加元素 opdata.container.append(`
--
银行名称
`); // 更新数据 $5('[data-num="n1"]', opdata.container).text(data.n1); $5('[data-bank]', opdata.container).text(data.name); ``` ### 使用 bigscreen 资源 #### 字体选择 ```css /* 大屏主标题 */ font-family: fnt01; font-size: 2em; letter-spacing: 0.2em; /* 中等标题 */ font-family: fnt02; font-size: 1.5em; /* 数字展示 */ font-family: eng02; font-size: 1.8em; letter-spacing: 4px; ``` #### 边框选择 ```javascript // 添加边框容器 opdata.container.append(`
`); // 或在HTML中定义 var chartHTML = `
信贷团队统计
`; opdata.container.append(chartHTML); ``` #### 标题选择 ```javascript // 面板内部小标题 var titleHTML = `
图表标题
`; opdata.container.append(titleHTML); ``` ### 渐变文字效果 ```javascript // 标题渐变 var captionHTML = `
大屏标题
`; opdata.container.append(captionHTML); ``` ### 使用全局缩放比例 ```javascript // 在所有尺寸计算中使用 Glob.bet var option = { textStyle: { fontSize: Glob.fontsize }, series: [{ itemStyle: { borderRadius: 4 * Glob.bet, borderWidth: 1 * Glob.bet }, label: { fontSize: 18 * Glob.bet, padding: [18 * Glob.bet, 0, 8 * Glob.bet, 0] }, labelLine: { length: 20 * Glob.bet, length2: 80 * Glob.bet } }] }; // CSS样式 var style = document.createElement("style"); style.innerHTML = ` .bank1-c1__num { font-size: 1.8em; padding: 10px * ${Glob.bet}; } `; ``` ### 动画效果 ```javascript // 透明度动画 @keyframes opa { 0% { opacity: 1; } 10% { opacity: 0.5; } 20% { opacity: 1; } } .ani-fade { animation: opa 5s infinite; } // ECharts自动高亮动画 var idx_autohight = -1; var t_autohight = setInterval(function () { var option = chart1.getOption(); chart1.dispatchAction({ type: 'downplay', dataIndex: idx_autohight }); idx_autohight = (idx_autohight + 1) % option.series[0].data.length; chart1.dispatchAction({ type: 'highlight', dataIndex: idx_autohight }); }, 2200); // 记得在 distory() 中清理 this.distory = function () { clearInterval(t_autohight); if (chart1) chart1.dispose(); } ``` ### 弹窗样式 ```javascript // 弹窗样式 var style = document.createElement("style"); style.innerHTML = ` .popup-box { position: absolute; z-index: 999; transform: translateX(calc(-50%)) translateY(calc(-100% + 4px)); pointer-events: none; transition: all 0.5s; opacity: 0; } .popup-box > .box { border: 1px solid #6d8ef4; background: linear-gradient(344deg, #0753b2, #05254e); border-radius: 0.5em; padding: 0.5em; white-space: nowrap; color: #ffffff; pointer-events: all; } .popup-box > .line { height: 3em; width: 1px; margin: auto; border-left: 1px solid #0753b2; } .popup-box > .rlc { width: 7px; height: 7px; background: #0753b2; margin: auto; border-radius: 4px; } `; window.document.head.appendChild(style); ``` ### 性能优化建议 1. **减少重复初始化** ```javascript this.setdata = function (funame, data) { if (ce) return; // 地图只初始化一次 if (chart1) return; // 图表只初始化一次 // ...初始化代码 } ``` 2. **使用事件委托** ```javascript // 不推荐 $5('.item').on('click', function() { // ... }); // 推荐 opdata.container.on('click', '.item', function() { // ... }); ``` 3. **及时清理资源** ```javascript this.distory = function () { clearInterval(t_autohight); if (chart1) chart1.dispose(); if (cyc) cyc.distory(); if (ce) ce.destroy(); // 移除动态添加的样式 if (thos.style) thos.style.remove(); } ``` --- ## 总结 Ciyon数据大屏系统采用**组件化**、**模块化**的设计理念: ✅ **优点**: - 组件独立开发,易于维护 - 数据轮询自动化 - 屏幕自适应 - 支持多种可视化类型 - 丰富的CSS资源库(73个样式类 + 15种字体) 📌 **核心要点**: 1. 遵循命名规范(文件、接口、方法、CSS类名) 2. 实现三个核心方法:`setdata()`、`resize()`、`distory()` 3. 合理设置刷新频率,避免性能问题 4. 及时清理资源,防止内存泄漏 5. 使用BEM命名法避免CSS冲突 6. 充分利用bigscreen资源库(字体、边框、标题) 7. 使用 `Glob.bet` 实现屏幕自适应 🎨 **资源使用建议**: - 字体:`fnt01`(大标题)、`eng02`(数字) - 背景:`bd04`(现代海蓝色) - 边框:`brimg34`(常用)、`brimg03`(薄边框) - 标题:`cap09`(带倒影)、`cap02`(简洁) 🔧 **API核心**: - `ciyclass.bigpanel` - 面板管理 - `ciyfn.big_setbetsize()` - 屏幕缩放 - `ciyfn.big_resolution()` - 分辨率检查 - `ciyclass.bigcychange` - 值循环切换 --- **版本**:v2.0 **更新时间**:2026-03-15 **维护团队**:Ciyon开发团队