40 KiB
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
// 创建面板
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(右下)
基本结构:
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(`
<div id="chart1" style="height:100%;"></div>
`);
// 初始化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
namespace web\admin\demo\bs;
class index {
// 初始化接口
public static function json_init() {
$ret['title'] = '演示大屏';
$ret['orgid'] = 1;
return succjson($ret);
}
// 图表数据接口:命名规则 json_{面板名}_{图表名}
public static function json_bank_c1() {
$ret['n1'] = '11,303.2';
$ret['n2'] = '9,395.1';
$ret['n3'] = '53';
$ret['name'] = '中国农业银行';
return succjson($ret);
}
// 复杂数据:返回数组
public static function json_bank_l1() {
$ret['pie'] = array();
for ($i = 1; $i < 4; $i++) {
$ret['pie'][] = array(
'id' => $i,
'name' => '风控' . $i,
'value' => rand(100, 300)
);
}
return succjson($ret);
}
}
命名规范:
- 方法名:
json_{面板名}_{图表名} - 返回格式:使用
succjson($ret)统一返回JSON - 数据结构:简单类型、数组、对象均可
数据流机制
轮询机制
// 面板启动时设置刷新频率(单位: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. 重置倒计时
跨组件数据共享
// 全局数据对象
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
常用组件类型
数字卡片组件
// 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(`
<div class="num" data-num="n1">--</div>
<div class="title">贷款金额 (万元)</div>
`);
}
ECharts饼图组件
// 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('<div id="chart1"></div>');
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地图组件
// 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('<div id="map1"></div>');
}
图片轮播组件
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('<img src="" style="width:100%;height:100%;">');
}
高级功能
弹窗面板
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({});
}
地图弹窗提示
this.showpopup = function (html, pos) {
if (thos.popup) thos.popup.remove();
var oset = $5(opdata.container).offset();
thos.popup = $5('<div class="popup-box"><div class="box">' + html + '</div><div class="line"></div><div class="rlc"></div></div>');
thos.popup.css({
top: pos.y - oset.top,
left: pos.x - oset.left,
opacity: 1
});
opdata.container.append(thos.popup);
}
屏幕自适应
// 设置基准分辨率
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();
}
});
开发最佳实践
性能优化
- 减少重复初始化
this.setdata = function (funame, data) {
if (ce) return; // 地图只初始化一次
// ...初始化代码
}
- 使用全局缩放比例
var option = {
fontSize: 18 * Glob.bet, // 根据屏幕缩放
borderRadius: 4 * Glob.bet
};
- 及时清理定时器
this.distory = function () {
clearInterval(t_autohight);
if (chart1) chart1.dispose();
}
样式规范
/* 渐变文字 */
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;
}
调试技巧
// 开发模式
if (urlp.dev) {
console.log('组件名称', data);
// ...调试代码
}
// 查看当前刷新频率
console.log(funcsecs); // 查看所有接口的倒计时
// 手动刷新所有组件
setdata();
常见问题
Q1: 组件不显示数据?
检查:
this.func数组是否正确- 后端接口命名是否匹配
json_{func} setdata()方法是否正确处理数据
Q2: 地图不显示?
检查:
- 容器是否有高度:
style="height:100%" - 初始化前是否已添加DOM
- Cesium资源是否加载:
/zces108/Cesium.js
Q3: 窗口调整后图表变形?
解决:
window.addEventListener("resize", function () {
chtpls[ipl].resize(); // 调用每个面板的resize
});
Q4: 数据刷新太频繁?
调整:
chtpls['bank1'].run({
'bank_c1': 100 // 增加刷新间隔(单位:0.5秒)
});
开发流程
新建大屏步骤
-
创建目录和文件
web/admin/demo/bs/ ├── index.html ├── index.php └── b64/ -
编写 index.html
- 引入必要JS库
- 创建
ciyclass.bigpanel - 添加图表组件
-
编写 index.php
- 创建
json_init()接口 - 为每个组件创建数据接口
- 创建
-
开发组件JS文件
- 实现
setdata()、resize()、distory() - 添加DOM结构
- 初始化ECharts或其他库
- 实现
-
测试调试
- 使用
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 | 常规 |
使用示例:
/* 大屏标题 */
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: 100vhcolor: #ffffff- 背景图片设置为
repeat重复平铺
使用示例:
<body class="bd04">
<!-- 大屏内容 -->
</body>
边框样式(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 特有样式:
background: #ff000029;
color: #cc0000;
text-shadow: 1px 1px 0 #000000;
font-weight: bold;
使用示例:
<!-- 常用边框 -->
<div class="brimg34" style="padding:2px;">
<div id="map1" style="height:100%;"></div>
</div>
<!-- 薄边框 -->
<div class="brimg03" style="padding:10px;">
<div id="chart1" style="height:100%;"></div>
</div>
<!-- 警告文本 -->
<div class="brtxt01">警告信息</div>
标题样式(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) | ⭐⭐⭐⭐ |
通用标题样式:
background-clip: text;
-webkit-background-clip: text;
color: transparent;
text-align: center;
倒影效果(cap01, cap09):
-webkit-box-reflect: below -35px -webkit-linear-gradient(transparent, transparent 20%, rgba(0,0,0,0.23));
底部样式(1种)
| 类名 | 高度 | 背景 | 对齐 |
|---|---|---|---|
.btm01 |
20px | btm01.png(底部居中) | 居中 |
使用示例:
<!-- 推荐标题:带倒影大标题 -->
<div class="cap09">
<div data-title>数据大屏标题</div>
</div>
<!-- 简洁大标题 -->
<div class="cap02">
<div>简洁标题</div>
</div>
<!-- 复合标题 -->
<div class="cap08">
<h1>主标题</h1>
<h2>副标题</h2>
</div>
<!-- 底部装饰 -->
<div class="btm01">
<div>底部文字</div>
</div>
小标题样式(6种)
| 类名 | 高度 | 左边距 | 最小宽度 | 背景图 |
|---|---|---|---|---|
.tit05 |
30px | 50px | 230px | tit/05.png(左上角) |
.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种)
立方体展开动画
@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;
}
效果:屏幕中心的边框立方体快速放大旋转消失,形成炫酷的展开效果
全局基础样式
* {
user-select: none; /* 禁止文本选择 */
-webkit-user-select: none;
}
span {
vertical-align: middle; /* span垂直居中 */
}
img {
vertical-align: middle; /* 图片垂直居中 */
}
资源速查表
字体选择:
font-family: fnt01; /* 大屏主标题 ⭐⭐⭐⭐⭐ */
font-family: fnt02; /* 中等标题 ⭐⭐⭐⭐ */
font-family: eng02; /* 数字展示 ⭐⭐⭐⭐⭐ */
font-family: SimHei; /* 复合标题(cap08) ⭐⭐⭐⭐ */
背景选择:
<body class="bd04"> <!-- 推荐:现代海蓝色 ⭐⭐⭐⭐⭐ -->
<body class="bd01"> <!-- 通用深蓝 ⭐⭐⭐⭐ -->
<body class="bd02"> <!-- 深蓝+黑 ⭐⭐⭐ -->
<body class="bd03"> <!-- 备用深色 ⭐⭐⭐ -->
边框选择:
<div class="brimg34"> <!-- 推荐:常用边框 ⭐⭐⭐⭐⭐ -->
<div class="brimg03"> <!-- 薄边框+半透明背景 ⭐⭐⭐ -->
<div class="brimg21"> <!-- 透明边框 ⭐⭐⭐ -->
<div class="brtxt01"> <!-- 红色警告文本框 ⭐⭐⭐ -->
标题选择:
<div class="cap09"> <!-- 推荐:带倒影大标题 ⭐⭐⭐⭐⭐ -->
<div class="cap01"> <!-- 倒影效果 ⭐⭐⭐⭐ -->
<div class="cap02"> <!-- 简洁大标题 ⭐⭐⭐⭐ -->
<div class="cap08"> <!-- 复合标题 ⭐⭐⭐⭐ -->
<div class="btm01"> <!-- 底部装饰 ⭐⭐⭐ -->
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)') |
使用示例:
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 | 传递给后端的公共参数(每个组件独有) |
使用示例:
chtpls['bank1'].post = {
bankid: 123,
orgid: 1
};
方法详解
1. addplot(opn) - 添加图表组件
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
opn.jsname |
String | ✓ | 组件名称(如 'bank1_c1') |
opn.style |
String | - | 组件容器样式 |
opn.prop |
String | - | 组件容器HTML属性 |
使用示例:
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 | - | - | 自定义点击事件 |
使用示例:
// 使用内置模板
chtpls['bank1'].setbtns({
template: 'close1',
hideopacity: 0.9,
hidesec: 5,
top: '2px'
});
// 自定义按钮
chtpls['bank1'].setbtns({
html: '<button data-act="close">关闭</button>',
click: function(e) {
console.log('按钮被点击');
}
});
内置模板:
close1- 关闭按钮(右上角×)
自动隐藏机制:
- 监听
mousemove事件更新时间戳 - 每500ms检查是否超过
hidesec秒未操作 - 超时则降低透明度到
hideopacity
3. run(fsec) - 启动数据轮询
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
fsec |
Object | ✓ | 刷新频率配置(键为接口名,值为0.5秒的倍数) |
使用示例:
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--(倒计时递减)
数据分发逻辑:
// 遍历所有组件
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() - 手动刷新所有组件
参数:无
功能:临时方法,用于调试或手动触发刷新
使用示例:
chtpls['bank1'].setdata();
5. resize() - 窗口大小改变响应
参数:无
功能:遍历所有组件,调用其 resize() 方法
使用示例:
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元素
使用示例:
chtpls['bank1'].distory();
delete chtpls['bank1'];
工具函数:ciyfn.big_setbetsize(basewidth, fontsize)
功能:设置大屏缩放比例和字体大小
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
basewidth |
Number | ✓ | - | 基准设计宽度(如 1536) |
fontsize |
Number/String | - | 'auto' |
字体大小('auto' 或 具体数值) |
返回值:无
使用示例:
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
使用场景:
// 页面加载时
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 | ✓ | 基准高度 |
返回值:无
使用示例:
ciyfn.big_resolution(1536, 864);
检查流程:
1. 检查物理分辨率:window.screen.width/height
└─ 不匹配?提示:"最佳分辨率为:1536 x 864"
2. 检查窗口宽度:window.innerWidth
└─ 不等于基准宽度?返回(判断为调试模式)
3. 检查窗口高度:window.innerHeight
└─ 小于基准高度?提示:"请按F11,进入全屏模式"
使用场景:
// 页面加载时检查
ciyfn.big_resolution(1536, 864);
类:ciyclass.bigcychange
功能:值循环切换工具(用于图片轮播、数据切换等)
构造函数参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
values |
Array | ✓ | - | 值数组 |
changecb |
Function | ✓ | - | 值改变时的回调函数 |
cycsec |
Number | - | 5 |
切换间隔(秒) |
使用示例:
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)
使用示例:
cyc.change('img2.jpg', 10); // 切换到'img2.jpg',停留10秒
cyc.change('img1.jpg'); // 切换到'img1.jpg',使用默认间隔
2. distory() - 销毁定时器
参数:无
返回值:无
使用示例:
cyc.distory();
完整使用示例:
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('<img src="" style="width:100%;height:100%;">');
}
全局变量:Glob
| 属性 | 类型 | 说明 |
|---|---|---|
Glob.post |
Object | 传递给后端的公共参数(所有面板共享) |
Glob.bet |
Number | 屏幕缩放比例 |
Glob.fontsize |
Number | 字体大小 |
Glob.myparam |
Object | 自定义参数 |
使用示例:
// 页面加载时设置公共参数
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命名法
/* 面板_组件__元素 */
.bank1-c1__num { }
.bank1-c1__title { }
.farm1-l2__info { }
.farm1-l2__item { }
示例:
opdata.container.append(`
<div class="bank1-c1">
<div class="bank1-c1__num" data-num="n1">--</div>
<div class="bank1-c1__title">贷款金额</div>
</div>
`);
// 动态注入样式
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)
// 添加元素时指定ID
opdata.container.append('<div id="chart1"></div>');
// 访问时限定在容器内
var chart1 = echarts.init($5('#chart1', opdata.container)[0], 'dark');
data-* 属性选择器
// 添加元素
opdata.container.append(`
<div data-num="n1">--</div>
<div data-bank>银行名称</div>
`);
// 更新数据
$5('[data-num="n1"]', opdata.container).text(data.n1);
$5('[data-bank]', opdata.container).text(data.name);
使用 bigscreen 资源
字体选择
/* 大屏主标题 */
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;
边框选择
// 添加边框容器
opdata.container.append(`
<div class="brimg34" style="padding:2px;height:100%;">
<div id="map1" style="height:100%;"></div>
</div>
`);
// 或在HTML中定义
var chartHTML = `
<div class="brimg03" style="padding:10px;background:#00000011;">
<div style="pointer-events:none;min-width:180px;padding-left:1.5em;">
<span style="color:#fffffd;font-weight:bolder;letter-spacing:2px;">信贷团队统计</span>
</div>
<div id="chart1" style="height:100%;z-index:5;"></div>
</div>
`;
opdata.container.append(chartHTML);
标题选择
// 面板内部小标题
var titleHTML = `
<div style="pointer-events:none;min-width:180px;padding-left:1.5em;">
<span style="color:#fffffd;font-weight:bolder;letter-spacing:2px;">图表标题</span>
<div style="position:relative;margin-top:0.6em;">
<img src="/ud/bigscreen/tit/05.png" style="height:0.3em;display:block;">
<div style="position:absolute;left:12em;right:1.5em;border-bottom:0.05em solid #64ecf7;"></div>
</div>
</div>
`;
opdata.container.append(titleHTML);
渐变文字效果
// 标题渐变
var captionHTML = `
<div style="font-family:fnt01;position:absolute;top:0;left:0;right:0;z-index:10;">
<img src="/ud/bigscreen/caption/09-og.png" style="height:3.5em;margin:auto;display:block;" />
<div data-title style="min-width:50em;position:absolute;top:0;left:0;right:0;text-align:center;line-height:1.7em;font-size:2em;
background: linear-gradient(to bottom, #ffffff, #50c4eb 60%);
background-clip: text;
-webkit-background-clip: text;
color: transparent;">
大屏标题
</div>
</div>
`;
opdata.container.append(captionHTML);
使用全局缩放比例
// 在所有尺寸计算中使用 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};
}
`;
动画效果
// 透明度动画
@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();
}
弹窗样式
// 弹窗样式
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);
性能优化建议
- 减少重复初始化
this.setdata = function (funame, data) {
if (ce) return; // 地图只初始化一次
if (chart1) return; // 图表只初始化一次
// ...初始化代码
}
- 使用事件委托
// 不推荐
$5('.item').on('click', function() {
// ...
});
// 推荐
opdata.container.on('click', '.item', function() {
// ...
});
- 及时清理资源
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种字体)
📌 核心要点:
- 遵循命名规范(文件、接口、方法、CSS类名)
- 实现三个核心方法:
setdata()、resize()、distory() - 合理设置刷新频率,避免性能问题
- 及时清理资源,防止内存泄漏
- 使用BEM命名法避免CSS冲突
- 充分利用bigscreen资源库(字体、边框、标题)
- 使用
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开发团队