<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          動態(tài)刻度可視化組件實現(xiàn)

          共 3317字,需瀏覽 7分鐘

           ·

          2021-09-30 09:29

          前言

          之前有個網(wǎng)友問我了一個很有價值的問題, 有關(guān)實現(xiàn)數(shù)據(jù)可視化的問題, 但是這個可視化問題不是一般的柱狀圖, 折現(xiàn)圖之類的,而是不規(guī)則刻度的數(shù)據(jù)可視化.所以筆者思考了一下決定自己實現(xiàn)一個動態(tài)刻度可視化組件的方案, 來解決這一類的需求.

          正文

          最初的需求是這樣的:

          我們只需要輸入文字, 數(shù)值比例, 就能生成如上圖所示的刻度圖.但是作為一名有追求的程序員, 需要對問題抽象化, 形成通用的解決方案,所以我們開始重組需求:

          由上圖我們可以拆解為一下幾個需求點:
          • 支持數(shù)值自定義
          • 數(shù)值單位自定義
          • 支持刻度組件寬度自定義
          • 支持刻度線數(shù)量自定義
          • 支持刻度變化幅度自定義
          • 傳入已有進度比例,即激活區(qū)范圍
          • 支持刻度樣式自定義
          • 支持數(shù)值樣式自定義
          • 支持自定義說明文本以及說明文本自定義
          以上就是筆者挖掘的通用需求,當(dāng)然有其他需求也可以漸進的增加.

          確認了以上需求之后,我們開始選擇技術(shù)選型, 筆者之前常用的技術(shù)棧是vuereact,所以接下來我們初步確認該組件采用如下技術(shù)方案:

          • react + typescript + umi-library

          如果大家擅長使用vue, 也可以, 筆者之前也寫過如何搭建vue組件庫相關(guān)的文章,感興趣可以學(xué)習(xí)了解一下, 其本質(zhì)思想是一致的.

          接下來我們開始實現(xiàn)動態(tài)刻度可視化組件. 如果對umi不熟悉的,可以參考筆者之前寫的文章從0到1教你搭建前端團隊的組件系統(tǒng)(高級進階必備).

          1. 定義基本屬性類型

          由以上需求分析我們可以定義如下的屬性類型:
          export interface TickerProps {
          width: number;
          maxHeight: number;
          percent: number;
          text: string;
          value: number;
          showValue: boolean;
          unit: string;
          lineNum: number;
          defaultColor: string;
          activeColor: string;
          textStyle: object;
          valueStyle: object;
          }

          復(fù)制代碼

          2. 組件整體結(jié)構(gòu)

          const Ticker: React.FC<TickerProps> = function(props:TickerProps) {
          const {
          width = 100,
          maxHeight = 10,
          percent = 50,
          value,
          text = '瞬時能見度',
          showValue = true,
          unit = 'M',
          lineNum = 12,
          defaultColor = '#06c',
          activeColor = 'red',
          valueStyle,
          textStyle
          } = props
          return (
          <div className="ticker">
          {
          showValue &&
          <div className="value" style={valueStyle}>
          { value || 0 } <span className="unit">{ unit }</span>
          </div>
          }
          <div className="tickerGraph">
          <div className="tickerLine">

          </div>
          <div className="tickerBar"></div>
          </div>
          {
          !!text && <div className="text">{ text }</div>
          }
          </div>
          );
          };

          export default Ticker;

          復(fù)制代碼

          3. 視圖搭建

          有關(guān)刻度可視化我們完全采用dom實現(xiàn), 所以這里筆者具體分析一下如何實現(xiàn)刻度視圖:

          上圖的思路就是用一個個dom來組裝成隨機刻度圖形,所以我們只要利用css實現(xiàn)這個形狀, 也就成功了一半.至于激活狀態(tài),我們會根據(jù)傳入的數(shù)據(jù)量來決定激活范圍,接下來會介紹如何渲染激活的刻度,也就是上圖的紅色區(qū)域.

          4.特殊功能實現(xiàn)

          因為該組件很多功能在搭建結(jié)構(gòu)之后已經(jīng)實現(xiàn)了, 這里我們唯一關(guān)注的就是cssjs長度計算的問題, css實現(xiàn)方案有很多, 這里就不具體介紹了, 筆者這里重點介紹一下如何實現(xiàn)指定范圍的隨機高度:

          // 生成指定范圍的隨機高度
          const random = (min:number, max:number):number => {
          return min + Math.random() * (max - min)
          }

          復(fù)制代碼

          動態(tài)刻度條的隨機高度我們就是利用以上函數(shù)實現(xiàn)的, 刻度條內(nèi)部實現(xiàn)如下:

          <div className="tickerLine" style={{borderBottomColor: defaultColor}}>
          {
          new Array(lineNum).fill(0).map((item:number, i: number) => {
          let isActive = (i + 1) <= Math.floor(lineNum * percent / 100)
          return <span
          className="tick"
          style={{
          height: random(3, maxHeight) + 'px', left: (gap + 2) * i + 'px',
          backgroundColor: isActive ? activeColor : defaultColor
          }}>
          </span>
          })
          }
          </div>
          復(fù)制代碼

          gap為刻度之間的間距, 由于計算刻度的位置需要一點幾何知識, 公式如下:

          W = Lw * lineNum + gap * ( lineNum - 1)
          復(fù)制代碼
          其中W表示刻度總寬度, Lw為刻度線寬度, lineNum為刻度線數(shù)量.

          還有一個注意點就是激活態(tài), 筆者使用如下函數(shù)來判斷刻度是否具有激活狀態(tài):

          let isActive = (i + 1) <= Math.floor(lineNum * percent / 100)
          復(fù)制代碼

          這塊也非常好理解, 也就是我們傳入的比率乘以線的總數(shù)量,即可求出哪些刻度線是需要激活的.

          以上細節(jié)實現(xiàn)完成之后,我們就可以來實現(xiàn)有點意思的刻度可視化方案啦, 如下展示的demo:


            1. 可見度測量


            1. 正態(tài)分布模型


            1. 標(biāo)尺


            1. 光柵


            1. 自定義文本樣式

          github地址

          https://github.com/MrXujiang/ticker

          最后

          如果想學(xué)習(xí)更多H5游戲webpacknodegulpcss3javascriptnodeJScanvas數(shù)據(jù)可視化等前端知識和實戰(zhàn),歡迎在公號《趣談前端》加入我們的技術(shù)群一起學(xué)習(xí)討論,共同探索前端的邊界。

          瀏覽 38
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大鸡吧视频在线免费观看 | 嫩苞又嫩又紧AV无码 | 爱久在线a| 亚洲综合免费观看高清完整版在线观 | 成年人激情网 |