久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      基于HTML5的Web SCADA報(bào)表圖文代碼詳解

      背景

      最近在一個(gè) SCADA 項(xiàng)目中遇到了在 Web 頁面中展示設(shè)備報(bào)表的需求。一個(gè)完整的報(bào)表,一般包含了篩選操作區(qū)、表格、Chart、展板等多種元素,而其中的數(shù)據(jù)表格是最常用的控件。在以往的工業(yè)項(xiàng)目中,所有的表格看起來千篇一律,就是通過數(shù)字和簡單的背景顏色變化來展示相關(guān)信息。但是現(xiàn)在通過各種移動(dòng) App 和 Web 應(yīng)用的熏陶,人們的審美和要求都在不斷提高,尤其是在 Web 項(xiàng)目中,還采用老式的數(shù)字表格確實(shí)也有點(diǎn)落伍了。

      如何選擇一個(gè)合適的 HTML 前端表格控件?此處可以省略一萬字。哈哈。jQuery、Angular、React 等陣營中的控件庫中都有不少成熟案例,但是這些基于 DOM 的控件也有不足,一個(gè)是效率問題:如果在數(shù)據(jù)量很大表格的中采用自定義的單元格控件,對(duì)瀏覽器的負(fù)擔(dān)實(shí)在太重,尤其是移動(dòng)端。另一個(gè)問題是開發(fā)效率,上述的控件庫中各自的封裝程度、接口形式都有所不同,但整體上還是要求開發(fā)者對(duì) CSS、JS 都有較深的了解。還有控件的復(fù)用、嵌入、發(fā)布、移植,也都是問題。

      基于上面的考慮,最后采用了基于 Canvas 的 HT。通過 HT 表格控件的自定義渲染接口,以及 Web Worker 的多線程數(shù)據(jù)模擬,實(shí)現(xiàn)的表格控件效果如下:

      基于HTML5的Web SCADA報(bào)表圖文代碼詳解

      開始

      首先我們要做的就是結(jié)合業(yè)務(wù)邏輯,對(duì)表格中不同列的數(shù)據(jù),進(jìn)行不同的渲染。例如設(shè)備歷史信息中的運(yùn)行時(shí)間、停機(jī)時(shí)間等,比較適合用餅圖來匯總展示,用戶就可以很直觀的從列表上對(duì)比出設(shè)備的歷史狀況。 我們來看看這一步是怎樣實(shí)現(xiàn)的。

      HT 有自己的 DataModel 數(shù)據(jù)模型,省略了我們對(duì)數(shù)據(jù)狀態(tài)管理、時(shí)間派發(fā)、ui刷新的開發(fā)工作。DataModel 容器中的子元素 Data,即是 HT 中最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),可以映射到不同的ui控件上。在畫布上,Data 可以展示成矢量、圖片或者文字等,在樹形控件上,Data 展示為樹的一個(gè)節(jié)點(diǎn)。在表格當(dāng)中每個(gè) Data 對(duì)應(yīng)著表格中的一行 Row。 也就是表格控件自身包含一個(gè) DataModel,在繪制時(shí),將這個(gè) Model 中的每個(gè) Data 都繪制成一行。 不同的列,展示的是該 Data 中的不同屬性。例如我們可以把設(shè)備的停機(jī)時(shí)間,保存到 Data 的 stopping 屬性。 在配置表格的列 Column 信息時(shí),我們可以指定該列的表頭描述“停機(jī)時(shí)間”,其數(shù)據(jù)單元格對(duì)應(yīng) Data 的 Stopping 屬性,以及自定義繪制格式:

      {      name: 'stopping',       //對(duì)應(yīng)的data屬性      accessType: 'attr',      align: 'center',              color: '#E2E2E2',       //文字顏色      displayName: '停機(jī)',    //表頭描述      drawCell: pageTable.getDrawLegend('stopping','#E2E2E2')  },

      自定義渲染

      在單元格的基本顯示格式中,已經(jīng)默認(rèn)提供了文本、數(shù)組、顏色等類型,可以自動(dòng)的對(duì)數(shù)據(jù)格式化,并展示為文字或背景顏色等,但是還未滿足我們的個(gè)性需求,因此就要將 Column 中的 drawCell 重載為自定義的渲染函數(shù)。 drawCell 的參數(shù):function (g, data, selected, column, x, y, w, h, view),其中 g 是 Canvas 的環(huán)境信息,data 是該行的數(shù)據(jù)體,我們根據(jù)這些信息,再利用 HTML5 原生的 Canvas API 就可以畫出想要的效果。

      懶得親自直接用 HTML5 的原生接口? HT 提供了對(duì) Canvas API 的封裝接口,包括各種矢量類型以及一些簡單的 Chart。利用該功能,可以輕松組合出復(fù)雜的效果,具體介紹可以參考我們的矢量手冊(cè)

      先創(chuàng)建一個(gè)對(duì)象,該 image 矢量對(duì)象負(fù)責(zé)包含對(duì)組合矢量的描述信息,然后將該 image 對(duì)象以及 drawCell 的上下文信息,作為參數(shù)傳入 ht.Default.drawStretchImage 函數(shù),即可實(shí)現(xiàn)自定義繪制。

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

      因?yàn)橛卸鄠€(gè) Legend 圖例顯示的列,所以我們可以簡單包裝一下,用了一個(gè) getDrawLegend 函數(shù),參數(shù)是該列圖例的顏色及 Data 屬性名稱,返回值是 drawCell 函數(shù)。

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

      至此,我們就完成了啟停時(shí)間這幾列的自定義繪制:

      基于HTML5的Web SCADA報(bào)表圖文代碼詳解

      “統(tǒng)計(jì)”列的餅圖,實(shí)際上更簡單。還是利用 HT 的矢量接口,把上述幾項(xiàng)時(shí)間數(shù)據(jù)傳入餅圖矢量結(jié)構(gòu)即可。

      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          }      ]  };

      其他列的渲染過程大同小異。在“風(fēng)速”列中,我們可以根據(jù)風(fēng)速大小計(jì)算一個(gè)顏色透明值,來實(shí)現(xiàn)同一色系的映射變換,比原來那種非紅即綠的報(bào)警表,看起來更舒服一些。在“可用率”列,用 Rect 的不同長度變化,來模擬進(jìn)度條的效果。在功率曲線中稍微有點(diǎn)不同,因?yàn)橄雽?shí)現(xiàn)曲線覆蓋區(qū)域的顏色漸變,在 HT 的 lineChart 中沒有找到相關(guān)接口,所以直接采用了 Canvas 繪制。

      基于HTML5的Web SCADA報(bào)表圖文代碼詳解

      為了運(yùn)行效率考慮,在表格的單元格中繪制 Chart,應(yīng)該追求簡潔大方,一目了然。這幾個(gè) Legend 圖例小矩形,其實(shí)是應(yīng)該畫在表頭的。我為了偷懶,就畫在了單元格,導(dǎo)致畫面顯得有點(diǎn)亂。

      Web Worker

      眾所周知,瀏覽器的 JS 環(huán)境是基于單進(jìn)程的,在頁面元素較多,而且有很大運(yùn)算需求的情況下,會(huì)導(dǎo)致無法兼顧渲染任務(wù)和計(jì)算任務(wù),造成頁面卡頓或失去響應(yīng)。在這種情況,可以考慮使用 Web Worker 的多線程,來分擔(dān)一些計(jì)算任務(wù)。

      Web Worker 是 HTML5 的多線程 API,和我們?cè)瓉韨鹘y(tǒng)概念中的多線程開發(fā)有所不同。Web Worker 的線程之間,沒有內(nèi)存共享的概念,所有信息交互都采用 Message 的異步傳遞。這樣多線程之間無法訪問對(duì)方的上下文,也無法訪問對(duì)方的成員變量及函數(shù),也不存在互斥鎖等概念。在消息中傳遞的數(shù)據(jù),也是通過值傳遞,而不是地址傳遞。

      在 Demo 中,我們利用 Web Worker 作為模擬后端,產(chǎn)生虛擬數(shù)據(jù)。并采用前端分頁的方式,從 worker 獲取當(dāng)前頁顯示條目的相關(guān)數(shù)據(jù)。 在主線程中,創(chuàng)建 Web Worker注冊(cè)消息監(jiān)聽函數(shù)。

      worker = new Worker("worker.js");      worker.addEventListener('message', function(e) {        //收到worker的消息后,刷新表格      pageTable.update(e.data);  });    pageTable.request = function(){    //向worker發(fā)送分頁數(shù)據(jù)請(qǐng)求      worker.postMessage({          pageIndex: pageTable.getPageIndex(),          pageRowSize: pageTable.getPageRowSize()              });                   };   pageTable.request();

      本處的new Worker創(chuàng)建,對(duì)于主線程來說是異步的,等加載完 worker.js,并完成初始化后,該 worker 才是真正可用狀態(tài)。我們不需要考慮 worker 的可用狀態(tài),可以在創(chuàng)建語句后直接發(fā)送消息。在完成初始化之前向其發(fā)送的請(qǐng)求,都會(huì)自動(dòng)保存在主線程的臨時(shí)消息隊(duì)列中,等 worker 創(chuàng)建完成,這些信息會(huì)轉(zhuǎn)移到 worker 的正式消息隊(duì)列。

      在 worker 中,創(chuàng)造虛擬隨機(jī)數(shù)據(jù),監(jiān)聽主線程消息,并返回其指定的數(shù)據(jù)。

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

      由于前面提到的無法內(nèi)存共享,Web Worker 無法操作 Dom,也不適用于與主線程進(jìn)行大數(shù)據(jù)量頻繁的交互。那么在生產(chǎn)環(huán)境中,Web Worker 能發(fā)揮什么作用?在我們這種應(yīng)用場(chǎng)景,Web Worker 適合在后臺(tái)進(jìn)行數(shù)據(jù)清洗,可以對(duì)從后端取到的設(shè)備歷史數(shù)據(jù)進(jìn)行插值計(jì)算、格式轉(zhuǎn)換等操作,再配合上 HT 的前端分頁,就能實(shí)現(xiàn)大量數(shù)據(jù)的無壓力展示。

      分頁

      傳統(tǒng)上有后端分頁和前端分頁,我們可以根據(jù)實(shí)際項(xiàng)目的數(shù)據(jù)量、網(wǎng)速、數(shù)據(jù)庫等因素綜合考慮。

      采用后端分頁的話,可以簡化前端架構(gòu)。缺點(diǎn)是換頁時(shí)會(huì)有延遲,用戶體驗(yàn)不好。而且在高并發(fā)的情況下,頻繁的歷史數(shù)據(jù)查詢會(huì)對(duì)后端數(shù)據(jù)庫造成很大壓力。

      采用前端分頁,需要擔(dān)心的是數(shù)據(jù)量。整表的數(shù)據(jù)量太大,會(huì)造成第一次獲取時(shí)的加載太慢,前端資源占用過多。

      在本項(xiàng)目中,得益于給力的 GOLDEN 實(shí)時(shí)數(shù)據(jù)庫,我們可以放心的采用前端分頁。歷史數(shù)據(jù)插值、統(tǒng)計(jì)等操作可以在數(shù)據(jù)庫層完成,傳遞到前端的是初步精簡后的數(shù)據(jù)。在數(shù)千臺(tái)設(shè)備的歷史查詢中,得到的數(shù)據(jù)量完全可以一次發(fā)送,再由前端分頁展示。

      在某些應(yīng)用場(chǎng)景,我們會(huì)在表格中顯示一些實(shí)時(shí)數(shù)據(jù),這些數(shù)據(jù)是必須是動(dòng)態(tài)獲取的。類似在 Demo 中的趨勢(shì)刷新效果,我們可以在創(chuàng)建表格時(shí)批量獲取所有歷史數(shù)據(jù),然后再動(dòng)態(tài)向數(shù)據(jù)庫獲取當(dāng)前頁所需的實(shí)時(shí)數(shù)據(jù)。如果網(wǎng)速實(shí)在不理想,也可以先只獲取第一頁的歷史數(shù)據(jù),隨后在后臺(tái)線程慢慢接收完整數(shù)據(jù)。

      這樣的架構(gòu)實(shí)現(xiàn)了海量數(shù)據(jù)的快速加載,換頁操作毫無延遲,當(dāng)前頁面元素實(shí)時(shí)動(dòng)態(tài)刷新的最終效果。

      還有一些傳統(tǒng)客戶,喜歡在一張完整的大表上進(jìn)行數(shù)據(jù)篩選、排序等操作。

      我們可以把 Demo 中的數(shù)據(jù)總量改成一萬條,單頁數(shù)量也是一萬條,進(jìn)行測(cè)試:

      基于HTML5的Web SCADA報(bào)表圖文代碼詳解

      出乎意料的是,HT 面對(duì)上萬數(shù)據(jù)量的復(fù)雜表格,輕松經(jīng)受住了考驗(yàn)。頁面的滾動(dòng)、點(diǎn)擊等交互毫無影響,動(dòng)態(tài)刷新沒有延遲,表格加載、排序等操作時(shí),會(huì)有小的卡頓,在可接受的程度之內(nèi)。當(dāng)然也跟客戶端的機(jī)器配置有關(guān)??梢韵胂螅瑤兹f個(gè) Chart的展示以及動(dòng)態(tài)刷新,對(duì)于基于dom的控件幾乎是件無法完成的任務(wù)。關(guān)于 HT 的其他矢量和控件,同樣有高性能特性:

      后記

      如前文所述,我們基于 HT 的表格實(shí)現(xiàn)了海量數(shù)據(jù)的可定制展現(xiàn),并取得了令人滿意的效果。以下是一些還可以改進(jìn)的地方。

      在 Demo 中,通過對(duì) HT 表格控件的 drawCell 進(jìn)行重載,實(shí)現(xiàn)了自定義渲染,然后把這些 drawCell 放到了 PageTable 的原型函數(shù)中,以供 Column 調(diào)用。實(shí)際上,更好的辦法應(yīng)該是把這些常見的 Chart、圖例封裝到 Column 的基本類型中,那樣在配置表格 Column 列時(shí),可以指定 type 為 pieChart 或 lineChart 即可,不需再自行繪制相關(guān)矢量。

      對(duì)于這些表格中的 Chart,也可以增加一些交互接口,例如可以增加單元格 Tooltip 的自定義渲染功能,在鼠標(biāo)停留時(shí)浮出一個(gè)信息量更大的 Chart,可以對(duì)指定設(shè)備進(jìn)行更深入的了解。
      界面美觀優(yōu)化。對(duì) HT 的控件進(jìn)行顏色定制,可以通過相關(guān)接口進(jìn)行配置:

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

      今后也可以對(duì)htconfig進(jìn)行全局配置,在單獨(dú)文件中進(jìn)行樣式的整體管理,實(shí)現(xiàn)外觀樣式與功能的分離,有助于工程管理。

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)