>  기사  >  웹 프론트엔드  >  HTML5 기반 Web SCADA 보고서의 그래픽 코드에 대한 자세한 설명

HTML5 기반 Web SCADA 보고서의 그래픽 코드에 대한 자세한 설명

黄舟
黄舟원래의
2017-04-01 11:05:453198검색

배경

최근 SCADA 프로젝트의 웹 페이지에 장비 보고서를 표시해야 할 필요성이 발생했습니다. 완전한 보고서에는 일반적으로 필터 작업 영역, 테이블, 차트, 디스플레이 보드 등과 같은 다양한 요소가 포함되며 그중 데이터 테이블이 가장 일반적으로 사용되는 컨트롤입니다. 이전 산업 프로젝트에서는 모든 테이블이 동일해 보였고 숫자와 간단한 배경색 변경을 통해 관련 정보를 표시했습니다. 그러나 이제 다양한 모바일 앱과 웹 애플리케이션의 영향으로 사람들의 미학과 요구 사항이 지속적으로 개선되고 있습니다. 특히 웹 프로젝트에서는 여전히 구식 디지털 테이블을 사용하는 것이 다소 구식입니다.

적절한 HTML 프런트 엔드 테이블 컨트롤을 선택하는 방법은 무엇입니까? 여기서는 1만 단어를 생략할 수 있습니다. 하하. jQuery, Angular, React 및 기타 캠프의 컨트롤 라이브러리에는 성숙한 사례가 많이 있지만 이러한 DOM 기반 컨트롤에도 단점이 있습니다. 하나는 효율성 문제입니다. 데이터, 특히 모바일에서는 브라우저의 부담이 너무 큽니다. 또 다른 문제는 개발 효율성입니다. 위에서 언급한 컨트롤 라이브러리는 캡슐화 정도와 인터페이스 형태가 다르지만 전반적으로 개발자는 CSS와 JS에 대한 깊은 이해가 필요합니다. 컨트롤의 재사용, 삽입, 게시 및 이식에도 문제가 있습니다.

위의 고려 사항을 바탕으로 마침내 Canvas 기반 HT가 채택되었습니다. HT 테이블 컨트롤의 사용자 정의 렌더링 인터페이스와 Web Worker의 멀티스레드 데이터 시뮬레이션을 통해 테이블 ​​컨트롤의 효과는 다음과 같습니다.

HTML5 기반 Web SCADA 보고서의 그래픽 코드에 대한 자세한 설명

시작

먼저 해야 할 일은 비즈니스 로직을 결합하여 테이블의 서로 다른 열에 서로 다른 데이터를 렌더링하는 것입니다. 예를 들어, 장비의 이력 정보 중 가동 시간, 다운타임 등은 요약하여 파이 차트로 표시하는 것이 더 적합합니다. 사용자는 목록에서 장비의 이력 상태를 직관적으로 비교할 수 있습니다. 이 단계가 어떻게 수행되는지 살펴보겠습니다.

HT에는 데이터 상태 관리, 시간 파견 및 UI 새로 고침에 대한 개발 작업이 생략된 자체 DataModel 데이터 모델이 있습니다. DataModel 컨테이너의 하위 요소 Data는 HT의 가장 기본적인 데이터 구조이며 다양한 UI 컨트롤에 매핑될 수 있습니다. 캔버스에서는 데이터를 벡터, 그림, 텍스트 등으로 표시할 수 있습니다. 트리 컨트롤에서는 데이터를 트리의 노드로 표시할 수 있습니다. 테이블의 각 데이터는 테이블의 행에 해당합니다. 즉, 테이블 컨트롤 자체에는 DataModel이 포함되어 있습니다. 그릴 때 이 모델의 각 데이터는 행으로 그려집니다. 열마다 데이터의 다양한 속성이 표시됩니다. 예를 들어 장치의 가동 중지 시간을 데이터의 중지 속성에 저장할 수 있습니다. 테이블의 열 정보를 구성할 때 "Downtime" 열의 헤더 설명을 지정할 수 있습니다. 해당 데이터 셀은 데이터의 Stopping 속성에 해당하며 사용자 정의 그리기 형식은

{
    name: 'stopping',       //对应的data属性
    accessType: 'attr',
    align: 'center',        
    color: '#E2E2E2',       //文字颜色
    displayName: '停机',    //表头描述
    drawCell: pageTable.getDrawLegend('stopping','#E2E2E2')
},

사용자 정의 렌더링

셀의 기본 표시 형식에는 텍스트, 배열, 색상 등의 형식이 기본적으로 제공되어 있지만, 데이터를 자동으로 포맷하여 텍스트나 배경색 등으로 표시할 수 있지만 아직까지는 만족스럽지 않습니다. 특성 요구사항이 있으므로 사용자 정의 렌더링 기능으로 Column에 drawCell을 오버로드해야 합니다. drawCell의 매개변수: 함수(g, data, selected, 열, x, y, w, h, view), 여기서 g는 Canvas의 환경 정보이고 data는 행의 데이터 본문입니다. 우리는 HTML5 네이티브를 사용합니다. Canvas API는 원하는 효과를 그릴 수 있습니다.

HTML5의 기본 인터페이스를 직접 사용하기에는 너무 게으른가요? HT는 다양한 벡터 유형과 일부 간단한 차트를 포함하여 Canvas API에 대한 캡슐화 인터페이스를 제공합니다. 이 기능을 사용하면 복잡한 효과를 쉽게 결합할 수 있습니다. 자세한 소개는 당사 벡터 매뉴얼

을 참조하세요. 먼저 이미지 벡터 객체는 결합된 벡터의 설명 정보를 담는 역할을 합니다. 이미지 객체를 결합하고 drawCell의 컨텍스트 정보가 ht.Default.drawStretchImage 함수에 매개변수로 전달되어 사용자 정의 드로잉을 구현합니다.

//drawCellfunction (g, data, selected, column, x, y, w, h, tableView) {    
var value = data.a(attr);    var image = {
        width: 60,
        height: 30,
        comps: [
            {
                type: 'rect',
                rect: [11,11,8,8],
                borderWidth: 1,
                borderColor: '#34495E',
                background: legendColor,
                depth: 3
            },
            {
                type: 'text',
                text: value,
                rect:[30, 0, 30, 30],
                align: 'left',
                color: '#eee',
                font: 'bold 12px Arial'
            }
        ]};
    ht.Default.drawStretchImage(g, image, 'centerUniform', x, y, w, h);
}

범례 범례에 표시되는 열이 여러 개 있으므로 이를 간단히 마무리하고 getDrawLegend 함수를 사용할 수 있습니다. 매개변수는 열 범례의 색상과 데이터 속성 이름이고 반환 값은 다음과 같습니다. drawCell 함수.

getDrawLegend: function(attr,legendColor){return drawCell}

이 시점에서 시작 및 중지 시간 열의 사용자 정의 그림이 완성되었습니다.

HTML5 기반 Web SCADA 보고서의 그래픽 코드에 대한 자세한 설명

“统计”列的饼图,实际上更简单。还是利用 HT 的矢量接口,把上述几项时间数据传入饼图矢量结构即可。

var values = [
    data.a('running'), 
    data.a('stopping'), 
    data.a('overhauling')
];var image = {
    width: 200,
    height: 200,
    comps: [
        {
            type: 'pieChart',
            rect: [20,20, 150, 150],
            hollow: false,
            label: false,
            labelColor: 'white',
            shadow: true,
            shadowColor: 'rgba(0, 0, 0, 0.8)',
            values: values,
            startAngle: Math.PI,
            colors: pieColors
        }
    ]
};

其他列的渲染过程大同小异。在“风速”列中,我们可以根据风速大小计算一个颜色透明值,来实现同一色系的映射变换,比原来那种非红即绿的报警表,看起来更舒服一些。在“可用率”列,用 Rect 的不同长度变化,来模拟进度条的效果。在功率曲线中稍微有点不同,因为想实现曲线覆盖区域的颜色渐变,在 HT 的 lineChart 中没有找到相关接口,所以直接采用了 Canvas 绘制。 

HTML5 기반 Web SCADA 보고서의 그래픽 코드에 대한 자세한 설명

为了运行效率考虑,在表格的单元格中绘制 Chart,应该追求简洁大方,一目了然。这几个 Legend 图例小矩形,其实是应该画在表头的。我为了偷懒,就画在了单元格,导致画面显得有点乱。

Web Worker

众所周知,浏览器的 JS 环境是基于单进程的,在页面元素较多,而且有很大运算需求的情况下,会导致无法兼顾渲染任务和计算任务,造成页面卡顿或失去响应。在这种情况,可以考虑使用 Web Worker 的多线程,来分担一些计算任务。 

Web Worker 是 HTML5 的多线程 API,和我们原来传统概念中的多线程开发有所不同。Web Worker 的线程之间,没有内存共享的概念,所有信息交互都采用 Message 的异步传递。这样多线程之间无法访问对方的上下文,也无法访问对方的成员变量及函数,也不存在互斥锁等概念。在消息中传递的数据,也是通过值传递,而不是地址传递。 

在 Demo 中,我们利用 Web Worker 作为模拟后端,产生虚拟数据。并采用前端分页的方式,从 worker 获取当前页显示条目的相关数据。 在主线程中,创建 Web Worker注册消息监听函数。

worker = new Worker("worker.js");    
worker.addEventListener('message', function(e) {  
    //收到worker的消息后,刷新表格
    pageTable.update(e.data);
});

pageTable.request = function(){    //向worker发送分页数据请求
    worker.postMessage({
        pageIndex: pageTable.getPageIndex(),
        pageRowSize: pageTable.getPageRowSize()        
    });                 
}; 
pageTable.request();

本处的new Worker创建,对于主线程来说是异步的,等加载完 worker.js,并完成初始化后,该 worker 才是真正可用状态。我们不需要考虑 worker 的可用状态,可以在创建语句后直接发送消息。在完成初始化之前向其发送的请求,都会自动保存在主线程的临时消息队列中,等 worker 创建完成,这些信息会转移到 worker 的正式消息队列。 

在 worker 中,创造虚拟随机数据,监听主线程消息,并返回其指定的数据。

self.addEventListener('message', function(e) {    
var pageInfo = getPageInfo(e.data.pageIndex, e.data.pageRowSize);   
    self.postMessage(pageInfo);
}, false);

由于前面提到的无法内存共享,Web Worker 无法操作 Dom,也不适用于与主线程进行大数据量频繁的交互。那么在生产环境中,Web Worker 能发挥什么作用?在我们这种应用场景,Web Worker 适合在后台进行数据清洗,可以对从后端取到的设备历史数据进行插值计算、格式转换等操作,再配合上 HT 的前端分页,就能实现大量数据的无压力展示。

分页

传统上有后端分页和前端分页,我们可以根据实际项目的数据量、网速、数据库等因素综合考虑。 

采用后端分页的话,可以简化前端架构。缺点是换页时会有延迟,用户体验不好。而且在高并发的情况下,频繁的历史数据查询会对后端数据库造成很大压力。 

采用前端分页,需要担心的是数据量。整表的数据量太大,会造成第一次获取时的加载太慢,前端资源占用过多。 

在本项目中,得益于给力的 GOLDEN 实时数据库,我们可以放心的采用前端分页。历史数据插值、统计等操作可以在数据库层完成,传递到前端的是初步精简后的数据。在数千台设备的历史查询中,得到的数据量完全可以一次发送,再由前端分页展示。 

在某些应用场景,我们会在表格中显示一些实时数据,这些数据是必须是动态获取的。类似在 Demo 中的趋势刷新效果,我们可以在创建表格时批量获取所有历史数据,然后再动态向数据库获取当前页所需的实时数据。如果网速实在不理想,也可以先只获取第一页的历史数据,随后在后台线程慢慢接收完整数据。 

这样的架构实现了海量数据的快速加载,换页操作毫无延迟,当前页面元素实时动态刷新的最终效果。 

还有一些传统客户,喜欢在一张完整的大表上进行数据筛选、排序等操作。 

我们可以把 Demo 中的数据总量改成一万条,单页数量也是一万条,进行测试:

HTML5 기반 Web SCADA 보고서의 그래픽 코드에 대한 자세한 설명

出乎意料的是,HT 面对上万数据量的复杂表格,轻松经受住了考验。页面的滚动、点击等交互毫无影响,动态刷新没有延迟,表格加载、排序等操作时,会有小的卡顿,在可接受的程度之内。当然也跟客户端的机器配置有关。可以想象,几万个 Chart的展示以及动态刷新,对于基于dom的控件几乎是件无法完成的任务。关于 HT 的其他矢量和控件,同样有高性能特性:

后记

如前文所述,我们基于 HT 的表格实现了海量数据的可定制展现,并取得了令人满意的效果。以下是一些还可以改进的地方。 

在 Demo 中,通过对 HT 表格控件的 drawCell 进行重载,实现了自定义渲染,然后把这些 drawCell 放到了 PageTable 的原型函数中,以供 Column 调用。实际上,更好的办法应该是把这些常见的 Chart、图例封装到 Column 的基本类型中,那样在配置表格 Column 列时,可以指定 type 为 pieChart 或 lineChart 即可,不需再自行绘制相关矢量。 

对于这些表格中的 Chart,也可以增加一些交互接口,例如可以增加单元格 Tooltip 的自定义渲染功能,在鼠标停留时浮出一个信息量更大的 Chart,可以对指定设备进行更深入的了解。 
界面美观优化。对 HT 的控件进行颜色定制,可以通过相关接口进行配置:

var tableHeader = pageTable.getTablePane().getTableHeader();    
tableHeader.getView().style.backgroundColor = 'rgba(51,51,51,1)';     
tableHeader.setColumnLineColor('#777');var tableView = pageTable.getTablePane().getTableView();                 
tableView.setSelectBackground('#3D5D73');
tableView.setRowLineColor('#222941');
tableView.setColumnLineVisible(false);                
tableView.setRowHeight(30);

今后也可以对htconfig进行全局配置,在单独文件中进行样式的整体管理,实现外观样式与功能的分离,有助于工程管理。

위 내용은 HTML5 기반 Web SCADA 보고서의 그래픽 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.