ciyon_ai/aiskill/ciyon-数据大屏.md
2026-04-15 17:28:46 +08:00

40 KiB
Raw Blame History

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();
    }
});

开发最佳实践

性能优化

  1. 减少重复初始化
this.setdata = function (funame, data) {
    if (ce) return;  // 地图只初始化一次
    // ...初始化代码
}
  1. 使用全局缩放比例
var option = {
    fontSize: 18 * Glob.bet,  // 根据屏幕缩放
    borderRadius: 4 * Glob.bet
};
  1. 及时清理定时器
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: 组件不显示数据?

检查

  1. this.func 数组是否正确
  2. 后端接口命名是否匹配 json_{func}
  3. setdata() 方法是否正确处理数据

Q2: 地图不显示?

检查

  1. 容器是否有高度:style="height:100%"
  2. 初始化前是否已添加DOM
  3. Cesium资源是否加载/zces108/Cesium.js

Q3: 窗口调整后图表变形?

解决

window.addEventListener("resize", function () {
    chtpls[ipl].resize();  // 调用每个面板的resize
});

Q4: 数据刷新太频繁?

调整

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 开发模式
    • 检查数据流
    • 优化性能

参考资源

技术文档

内部资源

  • 样式文件:/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: 100vh
  • color: #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 = 55秒后重试
   └─ 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);

性能优化建议

  1. 减少重复初始化
this.setdata = function (funame, data) {
    if (ce) return;  // 地图只初始化一次
    if (chart1) return;  // 图表只初始化一次
    // ...初始化代码
}
  1. 使用事件委托
// 不推荐
$5('.item').on('click', function() {
    // ...
});

// 推荐
opdata.container.on('click', '.item', function() {
    // ...
});
  1. 及时清理资源
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开发团队